| by Achyut Kendre | No comments

What is EF Core? How to use it in ASP.NET Core?

ASP.NET Core
ASP.NET Core Tutorial

Link to download example 1: https://drive.google.com/file/d/1U3YNSJxmq70BLSb8w3QUD2fQtD6ysv6K/view?usp=sharing

Link To download example 2 : https://drive.google.com/file/d/10j2OjwUkNcVQKcwqq2Ph_8rxsqYSAbsB/view?usp=sharing

In this article we will learn about new ORM Entity Framework Core by Microsoft which is now a official data access platform.

What is ORM?

ORM is called object relation mapper. ORM links or maps the classes, properties , methods from a application code to table, collection and fields from database so that a programmer and developer can manipulate the relational data using object oriented code.

There are many ORM tools available in the market few of them are –

  • Entity Framework 6.0
  • Hibernate
  • N Hibernate
  • Subsonic
  • Data Object.NE
  • Entity Framework Core

What is EF Core?

EF Core is ORM tool launched with .NET Core is complete rewrite /new product by Microsoft which allow you to manipulate relational data using object oriented code.

Entity core if ORM (Object Relation Mapper) it help you to link classes, properties, collections from the program to fields, tables and rows from database.
It enables you to manipulate data using object oriented code. Microsoft already has Entity Framework 6.x in .NET Framework. Entity Core is entire rewrite, this ORM works with .NET Core as well as .NET Framework.

Why EF Core?

Few are the following reasons due to which we will prefer to use the entity framework –

  • It is microdot’s Official Data Access Platform
  • Open Source
  • Cross Platform – it works on Windows, Linux, Mac.
  • Can be used with .NET Framework as well as with .NET Core.

Approaches Supported By EF Core.

Entity Core support following two approaches –
Code First: – in code first approach is used if your database is not exists, we can create database by writing C#/VB Code. This is default and preferred Approach by the Entity Core. Code First fully supported by entity core
Database First:- is used if your database is already exits. This approach has very less support in entity core and you need to install every thing manually nothing is built in .

EF Core Package’s

Entity Framework provides following packages that we require –

PackagePurpose
Microsoft.EntityFrameworkCore.SqlServerThis nuget package contains SQL Server specific functionality
Microsoft.EntityFrameworkCore.RelationalThis nuget package contains functionality that is common to all relational databases
Microsoft.EntityFrameworkCoreThis nuget package contains common entity framework core functionality
Microsoft.EntityFrameworkCore.ToolsIt provides tools for nuget package manager console like Add-Migration

You can install these packages using NuGet package manager or package manager console.

What is DbContext?

DbContext is built in class which is part of Microsoft.AspNetCore.EntityFrameworkCore, The DbContext class is an integral part of Entity Framework. An instance of DbContext represents a session with the database which can be used to query and save instances of your entities to a database. DbContext is a combination of the Unit Of Work and Repository patterns.

DbContext in EF Core allows us to perform following tasks:

  • Manage database connection
  • Configure model & relationship
  • Querying database
  • Saving data to the database
  • Configure change tracking
  • Caching
  • Transaction management

Two methods we are going to use from dbcontext –
Entry :Gets an EntityEntry for the given entity. The entry provides access to change tracking information and operations for the entity. Using which we can modify/update the entity.

SaveChanges: Execute INSERT, UPDATE or DELETE command to the database for the entities with Added, Modified or Deleted state.

Let us create the project and use EF core step by step –

  1. Create ASP.NET Core Empty Project.
  2. Activate MVC and Define Default Route for MVC
  3. Install All Entity Framework Core Packages using nuget.
  4. Create Model classes with Data Annotation Attributes
  5. Create a DbContext class.
  6. Define Connection String
  7. Register DbContext class to IOC.
  8. Do Migration to create Database
  9. Inject DbContext object in Controller
  10. 10.Run Application

Create ASP.NET Core Empty Project

Create asp.net core project using regular steps required.

Activate MVC and Define Default Route for MVC

Activate MVC by adding following code in ConfigureSevices method of startup class –

services.AddControllersWithViews();

Activate Default Route using following code in Configure method of the startup class –

app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});

After this create the Cotnrollers folder and add HomeController and create the index view for index action.

Install All Entity Framework Core Packages using nuget.

You can install all the required packages using two ways using package manage console by firing commands or using GUI window.

If you want to install it using package manager console use the following commands, to open package manager console use the steps –

Install-Package Microsoft.EntityFrameworkCore -Version 3.1.1
Install-Package Microsoft.EntityFrameworkCore.Relational -Version 3.1.1
Install-Package Microsoft.EntityFrameworkCore.SqlServer -Version 3.1.1
Install-Package Microsoft.EntityFrameworkCore.Tools -Version 3.1.1

You can skip the version number if you want to install the latest packages.

Install these packages using Nuget GUI as follows –

To open nuget GUI right click on project and select manage nuget packages –

It shows following window go to browse option and search for EntityFramework Core.

Click on the Microsoft Entity Framework Core It will show you option to do the installation by selecting version required.

It shows a agreement accept window as follows click on accept button as follows –

After installation it will show the following screen –

Similar way you can install all the required packages –

Create Model classes with Data Annotation Attributes

Now you can create the following model classes using data annotations as follows –

  1. create area class as follows –
 [Table("AreaTbl")]
    public class Area
    {
        [Key]
        public Int64 AreaID { get; set; }
        public string AreaName { get; set; }
        public virtual List<Dept> Depts { get; set; }
    }

2. create dept class as follows

 [Table("Depttbl")]
    public class Dept
    {
        [Key]
        public Int64 DeptID { get; set; }
        public string DeptName { get; set; }
        public Int64 AreaID { get; set; }
        public virtual Area Area { get; set; }
        public virtual List<Emp> Emps{ get; set; }
    }

3. create emp class as follows

 [Table("EmpTbl")]
    public class Emp
    {
        [Key]
        public Int64 EmpID { get; set; }
        [Required(ErrorMessage ="Emp Name Required")]
        public string EmpName { get; set; }
        [Required(ErrorMessage ="Address Required")]
        public string Address { get; set; }
        [Required(ErrorMessage ="Email ID Required")]
        public string EmailID { get; set; }
        [Required(ErrorMessage ="Moile No Required")]
        public string MobileNo { get; set; }
        [Required(ErrorMessage ="Salary Required")]
        public decimal Salary { get; set; }
        [Required(ErrorMessage ="Dept Required")]
        public Int64 DeptID { get; set; }
        public virtual Dept Dept { get; set; }
    }

In above code we are using Data Annotation API and use attribute like – Table, Foregin Key, Virtual Properties for navigation properties.

Create a DbContext class.

To create DbContext class define your class with name CompanyContext and inherit it from built in class called DbContext part of EntityFrameworkCore Namesapce. DbContext act as a session between your program and application and does all necessary activities to modify the data or reflect data in database.

The DbContextOptions instance carries configuration information such as the connection string, database provider to use etc. In DbContext class we create a property of type DbSet properties for each entity in the model.

DbContext in EF Core allows us to perform following tasks:

  • Manage database connection
  • Configure model & relationship
  • Querying database
  • Saving data to the database
  • Configure change tracking

You can create it as follows –

public class CompanyContext:DbContext
 {
    public CompanyContext(DbContextOptions<CompanyContext> options) : base(options)
        { }
}

Since ASP.NET Core has built in dependency injections so when we create a context class it will be compulsory to define a constructor having DbContextOptions which will carry the information of Database Provider and connection string which will be passed to base class constructor.

Define DbSet type of generic properties for every model class that you want to be a table in database as follows –

public class CompanyContext:DbContext
 {
public CompanyContext(DbContextOptions<CompanyContext> options) : base(options)
        { }
    public DbSet<Area> Areas { get; set; }
    public DbSet<Dept> Depts { get; set; }
    public DbSet<Emp>   Emps { get; set; }

}

Define Connection String

Connection string is a string which contains the name of server , name of database and authentication information / security information. Can be defined as follows –

server=servername;initial catalog=database;Trusted_Connection=true

You can define a connection string in appsettings.json file as follows –

{
  "ConnectionStrings": {
    "scon": "server=DESKTOP-5J4VP0H\\SQLEXPRESS;initial catalog=cccDb22;Trusted_Connection=true"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

Register DbContext class to IOC.

In next step we need to register the DbContext class with IOC container using ConfigureServices method of Startup class using AddDbConetxt and AddDbContextPool extension method.

The difference is AddDbContxtPool() provides DbContext Pooling. With DbContext pooling, an instance from the DbContext pool is provided if available, rather than creating a new instance.

public class Startup
 {
  public void ConfigureServices(IServiceCollection services)
  {
  services.AddDbContextPool<CompanyContext>(options);
  }
}

Options here allow you to specify provider name, connection string as a parameter to options. For Sql Server provider we need to use UseSqlServer method in options parameter which can have the connection string as parameter.

UseSqlServer Extension Method:-

UseSqlServer() extension method is used to configure our application specific DbContext class to use SQL Server Database. §To connect to a da  tabase, we need the database connection string which is provided as a parameter to UseSqlServer() extension method. You can pass the connection string as parameter directly in UseSqlServer method –

services.AddDbContextPool<CompanyContext>(server=DESKTOP\\SQLEXPRESS;initial catalog=cccDb22;Trusted_Connection=true);

Another way is to read the connection string appsettings.json file. If you want to read any thing from appsettings.json we need IConfiguration service which need to be injected in a startup constructor.

IConfiguration config;
public Startup(IConfiguration ctemp)
 { 
    this.config=ctemp;
  }

Once you create the object of IConfiguration Service you can register the DbContext using following code –

services.AddDbContextPool<CompanyContext>(options => options.UseSqlServer(this.config.GetConnectionString("scon")));

Once you register the Dbcontext to IOC you can ask for it’s object in controller class as follows –

public class HomeController : Controller
{
    CompanyContext cc;
    public HomeController(CompanyContext cctemp)
     {
         this.cc = cctemp;
     }
}

You can then you can do normal curd operation using following code –

namespace CurdusingEntityCoreEx1.Controllers
{

    public class HomeController : Controller
    {
        CompanyContext cc;
        public HomeController(CompanyContext cctemp)
        {
            this.cc = cctemp;
        }
        public IActionResult Index()
        {
            return View(cc.Emps.ToList());
        }
        [HttpGet]
        public IActionResult Create()
        {
            ViewBag.Depts = new SelectList(cc.Depts.ToList(), "DeptID", "DeptName");
            return View();
        }

        [HttpPost]
        public IActionResult Create(Emp rec)
        {
            ViewBag.Depts = new SelectList(cc.Depts.ToList(), "DeptID", "DeptName");

            if (ModelState.IsValid)
            {
                this.cc.Emps.Add(rec);
                this.cc.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(rec);
        }

        [HttpGet]
        public IActionResult Edit(Int64 id)
        {
            var rec = this.cc.Emps.Find(id);
            ViewBag.Depts = new SelectList(cc.Depts.ToList(), "DeptID", "DeptName",rec.DeptID);

            return View(rec);
        }

        [HttpPost]
        public IActionResult Edit(Emp rec)
        {
            this.cc.Entry(rec).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
            this.cc.SaveChanges();
            return RedirectToAction("Index");
        }
        [HttpGet]
        public IActionResult Delete(Int64 id)
        {
            var rec = this.cc.Emps.Find(id);
            this.cc.Emps.Remove(rec);
            this.cc.SaveChanges();
            return RedirectToAction("Index");
        }
    }
}