In this article, we look at DBContext. We also look at how to create a DBContext class in our ASP.NET Core application. Next, we will show you how to register DBContext for Dependency Injection. Later we will take a look at how to configure DBContext using DbContextOptions & DbContextOptionsBuilder.
Table of Contents
What is DBContext
The DBContext is heart of the Entity Framework. It is the connection between our entity classes and the database. The DBContext is responsible for the database interactions like querying the database and loading the data into memory as entity. It also tracks the changes made to the entity and persists the changes to the database .
How to Use/Create DBContext
To use DBContext, we need to create a context class and derive it from the DbContext base class. The following is the example of the Context class (EFContext)
Creating the Context Class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public class EFContext : DbContext { public EFContext(DbContextOptions options) : base(options) { } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { //use this to configure the contex } protected override void OnModelCreating(ModelBuilder modelBuilder) { //use this to configure the model } public DbSet<Category> Categories { get; set; } public DbSet<Product> Products { get; set; } } |
The Context class above has a constructor which accepts the DbContextOptions as its argument. The dbContextOptions carries the configuration information needed to configure the DbContext.
The dbContextOptions can also be configured using the OnConfiguring method. This method gets the DbContextOptionsBuilder as its argument. It is then used to create the dbContextOptions
The OnModelCreating is the method where you can configure the model. The instance of the ModelBuilder is passed as the argument to the onModelCreating method. The ModelBuilder provides the API, which is used to configure the shape, data type, relationships between the models etc.
Finally, we define the DbSet property for the each entity ( database table). In the above example, Categories & products represents the database table Category & Product
Registering for the Dependency Injection
Next, we need to register our context class to be available via dependency injection. This is done under the ConfigureService method in the startup class
1 2 3 4 5 6 7 8 | public static IConfiguration Configuration { get; set; } public Startup(IConfiguration config) { Configuration = config; } |
1 2 3 4 5 6 7 8 9 10 | public void ConfigureServices(IServiceCollection services) { services.AddMvc(); var connectionString = Configuration.GetConnectionString("SQLConnection"); services.AddDbContext<EFContext>( options => options.UseSqlServer(connectionString) ); |
First, we need connection string , which can be obtained from the IConfiguration instance.
1 2 3 | var connectionString = Configuration.GetConnectionString("DefaultConnection"); |
Next, we use AddDbContext extension method to register the EFContext in the dependency Injection container. The first argument is of Action<T>, where you get the reference to the DbContextOptionsBuilder. The DbContextOptionsBuilder is used to configure the DbContextOptions
1 2 3 4 5 | services.AddDbContext<EFContext>( options => options.UseSqlServer(connectionString) ); |
The DbContextOptionsBuilder uses the UseSQLServer extension method, which registers the SQL Server database provider to be used with entity framework core. We pass the connection string to the UseSqlServer method
Injecting Context via constructor
Finally, we can use the context in the controller or in other services by using the dependency injection as shown below
1 2 3 4 5 6 7 8 | private EFContext db; public HomeController(EFContext EFContext) { db = EFContext; } |
Database Providers
The DBContext connects to the database using the Database Providers. In the example above we used the UseSqlServer extension method
The Database Provider are a set of API that used to connect to a particular database. There are many different database Providers currently available with the EF Core. You can find the complete list of database providers. The following is the some of the list of common database providers that are used.
Database | Package |
SQLite | Microsoft.EntityFrameworkCore. |
Microsoft SQL Server | Microsoft.EntityFrameworkCore.SqlServer |
Npgsql (PostgreSQL) | Npgsql.EntityFrameworkCore.PostgreSQL |
IBM Data Servers | IBM.EntityFrameworkCore |
MySQL (Official) | MySql.Data.EntityFrameworkCore |
Pomelo (MySQL) | Pomelo.EntityFrameworkCore.MySql |
InMemory (for Testing) | Microsoft.EntityFrameworkCore.InMemory |
Once you install the database provider, then you can configure the database provider using the extension method provided them using the DbContextOptionsBuilder
For Example to use SQL Server install the package
1 2 3 | Install-Package Microsoft.EntityFrameworkCore.SqlServer |
Then use the UseSqlServer extension method to register the SQL Server database provider. This can be done while registering the service
1 2 3 4 5 | services.AddDbContext<EFContext>( options => options.UseSqlServer(connectionString) ); |
OR by overriding the OnConfigure method
1 2 3 4 5 6 7 8 9 10 | protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { if (!optionsBuilder.IsConfigured) { optionsBuilder.UseSqlServer("Server=(localdb)\\MSSQLLocalDB;Database=EFCore;Trusted_Connection=True;MultipleActiveResultSets=true"); } } |
Configuring the DbContext
The DbContext is configured using the DbContextOptions.
DbContextOptions
The DBContext requires the DbContextOptions instance in order to perform any task.
The DbContextOptions instance carries configuration information such as the database providers to use, connection strings and any database related configuration information.
DbContextOptionsBuilder
We build DBContext options using the DbContextOptionsBuilder API
There are two ways you can build the DbContextOptions
One option is to create DbContextOptions externally and pass it in the constructor of DBContext class
The second option is to override the OnConfiguring(DbContextOptionsBuilder) method and create the DbContextOptions
Using the Constructor
To use the constructor first we need to define the Context constructor as shown here
1 2 3 4 5 | public EFContext(DbContextOptions options) : base(options) { } |
Here, we have two options.
One is to use the dependency injection, which is what we used in the example above.
1 2 3 4 5 | services.AddDbContext<EFContext>( options => options.UseSqlServer(connectionString) ); |
The AddDbContext not only registers the EFContext but also registers the DbContextOptions available for injection, which is provided as an Anonymous function
The second option is to create the DbContextOptions externally and pass it to while creating the context as shown in the following example
1 2 3 4 5 | var optionsBuilder = new DbContextOptionsBuilder<EFContext>(); optionsBuilder.UseSqlServer(connectionString); db = new EFContext(optionsBuilder.Options); |
Using the OnConfiguring Method
The second option is to use the OnConfiguring method to configure the DbContextOptions as shown below
1 2 3 4 5 6 7 8 9 10 | protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { if (!optionsBuilder.IsConfigured) { optionsBuilder.UseSqlServer("Server=(localdb)\\MSSQLLocalDB;Database=EFCore;Trusted_Connection=True;MultipleActiveResultSets=true"); } } |
It is possible to use both the Constructor & OnConfiguring method to configure the DbContext. In such a scenario the OnConfiguring is executed last. Hence any changes applied in the constructor is overwritten.
The optionsBuilder.IsConfigured returns a boolean value indicating whether any options have been configured.
Functions of DBContext
Managing Database connection
The DBContext opens and manages the database connection pool. It will reuse the connections wherever possible and creates a new connection only when needed.
Configuring Model & relationships
The DBContext builds the model based on a set of conventions. You can override those conventions by providing additional configuration to build the model. The Fluent API Provides more control over the building of models
The model configuration is done in the OnModelCreating method using the ModelBuilder API
Querying & Saving data to the database
In order to use Entity framework core, we need to define the DbSet property for each entity (or tables). Then we need to configure the model & define relationships between the entities using the ModelBuilder API
Once we have these in place, then we can Write and execute queries against those models, which gets translated to the database query and executed. The returned results are Materialized and converted to entity objects. Any changes made to those entities are persisted back to the database.
Change Tracking
The entities can be added/deleted or modified. The DBContext’s change tracker keeps track of these operations and sets the EntityState of each entity. This state is then used while saving the entity into the database, by generating the proper insert, alter, delete queries.
Transaction Management
By default each SaveChanges are wrapped in a single transaction.
You can control the transactions better by using DbContext.Database API. You can begin transaction commit, and rollback transactions
Summary
In this tutorial, we learnt what is DBContext. We also learnt how to configure it in ASP.NET MVC Core application. We also looked at various functions provided by the DBContext