DbContext class is the brain of Entity Framework Core and does all the communications with the database.
It allows performing the following tasks:
Page Contents
Let us create an example project to understand DBContext properly. I have named my new project as DB-Context. After that I did the Installation of Entity Framework Core in it.
This application will work with a Database of a very small company. The database has just 2 table which are:
For representing these 2 tables I will need to create 2 entity classes. So create 2 entity classes called Department.cs & Employee.cs inside the Models folder.
The codes of these classes are:
1. Department.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace DB_Context.Models
{
public class Department
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Employee> Employee { get; set; }
}
}
2. Employee.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace DB_Context.Models
{
public class Employee
{
public int Id { get; set; }
public int DepartmentId { get; set; }
public string Name { get; set; }
public string Designation { get; set; }
public Department Department { get; set; }
}
}
Now it’s time to create DbContext class.
In order to use the features of DbContext class, your application context class has to derive from it.
So first create a new context class and name it CompanyContext.cs. Place this class inside the Models folder. Derive it from DbContext class of the Microsoft.EntityFrameworkCore namespace.
The CompanyContext.cs will look like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
namespace DB_Context.Models
{
public class CompanyContext: DbContext
{
}
}
Next add the DbSet<T> for the 2 entity class which are Department and Employee.
This will make your CompanyContext class look this way:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
namespace DB_Context.Models
{
public class CompanyContext: DbContext
{
public DbSet<Department> Department { get; set; }
public DbSet<Employee> Employee { get; set; }
}
}
The OnConfiguring() method of the DbContext class is an override method. It allows to select and configure the data source to be used with a context. For this the DbContextOptionsBuilder class object is passed to it’s parameter.
On adding the OnConfiguring() method to the CompanyContext class it will look like:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
namespace DB_Context.Models
{
public class CompanyContext : DbContext
{
public DbSet<Department> Department { get; set; }
public DbSet<Employee> Employee { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer(@"Server=vaio;Database=Company;Trusted_Connection=True;");
}
}
}
}
Notice that I have passed the connection string to the UseSqlServer() method of the DbContextOptionsBuilder() class object.
The OnModelCreating() method of the DbContext class allows configuring the model using Fluent API. This method is also an override method.
After adding it to the CompanyContext class it will look:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
namespace DB_Context.Models
{
public class CompanyContext : DbContext
{
public DbSet<Department> Department { get; set; }
public DbSet<Employee> Employee { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer(@"Server=vaio;Database=Company;Trusted_Connection=True;");
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Department>(entity =>
{
entity.Property(e => e.Name)
.IsRequired()
.HasMaxLength(50)
.IsUnicode(false);
});
modelBuilder.Entity<Employee>(entity =>
{
entity.Property(e => e.Designation)
.IsRequired()
.HasMaxLength(25)
.IsUnicode(false);
entity.Property(e => e.Name)
.IsRequired()
.HasMaxLength(100)
.IsUnicode(false);
entity.HasOne(d => d.Department)
.WithMany(p => p.Employee)
.HasForeignKey(d => d.DepartmentId)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_Employee_Department");
});
}
}
}
Inside the OnModelCreating() method I have configured both the Department and the Employee entities. As you can see, by using the IsRequired() I am making the Name property of the Department class as the required one. Similarly the HasMaxLength(100) method is used to set the maximum length of Name property of the employee entity.
Some important methods of DbContext class are.
Method | Description |
---|---|
Add | Adds a new entity with Added state |
AddRange | Adds a collection of new entities with Added state |
Attach | Attaches a new or existing entity with Unchanged state |
AttachRange | Attaches a collection of new or existing entity with Unchanged state |
Remove | Attaches an entity with Deleted state |
RemoveRange | Attaches a collection of entities with Deleted state |
Update | Attaches disconnected entity with Modified state |
UpdateRange | Attaches collection of disconnected entity with Modified state |
SaveChanges | Execute INSERT, UPDATE or DELETE command to the database for the entities with Added, Modified or Deleted state. |
It’s time to run the Migrations in order to create the database from the entity classes.
On the Package Manager Console window run these 2 commands one by one:
1. Add Migration Command
PM> dotnet ef migrations add Migration1
After this command is executed you will find a new folder called Migrations is created in your project. Check the Solution Explorer in Visual studio to find 2 .cs files inside the Migrations folder. I have shown this in the below image.
2. Update Migration Command
Next run the below given command which will create the database from the migration files.
PM> dotnet ef database update
Now check the SQL server where you will find the Company database created. I have shown this in the below image.
Now it’s time to test if everything is working correctly or not. So let us insert a record into the database by the application and using Entity Framework core.
So create a controller called HomeController inside the Controllers folder and add the below code to it.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DB_Context.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace DB_Context.Controllers
{
public class HomeController : Controller
{
public string Index()
{
using (var context = new CompanyContext())
{
var dept = new Department()
{
Name = "Designing"
};
context.Entry(dept).State = EntityState.Added;
context.SaveChanges();
}
return "Record Interested";
}
}
}
Now run the project and initiate this action’s url in the browser. This will insert a new record on the Department table of the database. Open the table and you can check the newly added record. See the below image of the database table.
In the above code I have placed my database connection string in the OnConfiguring method of DBContext file. You may avoid this and would like to store the connection string in the appsettings.json file instead. Let us see how to do this.
First create appsettings.json on the project folder and add your DB connection string to it as shown below.
{
"ConnectionStrings": {
"DefaultConnection": "Server=vaio;Database=Company;Trusted_Connection=True;"
}
}
Some changes need to be done to CompanyContext class which is the DbContext for this project. These changes are:
These changes are shown below.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
namespace DB_Context.Models
{
public class CompanyContext : DbContext
{
public CompanyContext(DbContextOptions<CompanyContext> options) : base(options)
{
}
public DbSet<Department> Department { get; set; }
public DbSet<Employee> Employee { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Department>(entity =>
{
entity.Property(e => e.Name)
.IsRequired()
.HasMaxLength(50)
.IsUnicode(false);
});
modelBuilder.Entity<Employee>(entity =>
{
entity.Property(e => e.Designation)
.IsRequired()
.HasMaxLength(25)
.IsUnicode(false);
entity.Property(e => e.Name)
.IsRequired()
.HasMaxLength(100)
.IsUnicode(false);
entity.HasOne(d => d.Department)
.WithMany(p => p.Employee)
.HasForeignKey(d => d.DepartmentId)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_Employee_Department");
});
}
}
}
Register the CompanyContext, which is the DbContext for this project, as a service in startup class. Open Startup.cs, and add the highlighted lines to the ConfigureServices method.
I have shown this by highlighting the necessary code to be added. You will also need to inject IConfiguration by Dependency Injection to the Startup.cs class constructor.
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using DB_Context.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
namespace DB_Context
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<CompanyContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddControllersWithViews();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// ...
}
}
}
Now to perform EF core operations you have to inject the DbContext (here it is CompanyContext) in the controller through the Dependency Injection Feature of ASP.NET Core, and then use it to perform your db operations.
Check the below Entity Framework Code code where I am performing the Record Insertion into the database.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DB_Context.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace DB_Context.Controllers
{
public class HomeController : Controller
{
private CompanyContext context;
public HomeController(CompanyContext cc)
{
context = cc;
}
public string Index()
{
var dept = new Department()
{
Name = "Coding"
};
context.Entry(dept).State = EntityState.Added;
context.SaveChanges();
return "Record Interested";
}
}
}
You can download the source code from the below link.