[Entity Framework] DbContext API – DbContext Class

The main controller of EF(Entity Framework) is “System.Data.Objects.ObjectContext” class. When Code First was introduced, “DbContext” was also introduced.

System.Data.Entity.DbContext” is a stripped-down version of ObjectContext. DbContext makes developers to use more frequently used features more easily. When you use Code First, you will use DbContext too.

 

1. DbContext Class

When you work with EF with ObjectContext, you rarely create the context class by hand. EF wizard and designer takes care of the changes.

With Code First, developers need to take care of managing context object too. The EF team decides that ObjectContext might be too big and confusing with Code First, so they provides a new context object with a simple interface.

In fact, DbContext uses  ObjectContext under the hood. By doing so, DbContext works with EF.

The skeleton of DbContext class (validation related methods are omitted) is like this:

public class DbContext : IDisposable, IObjectContextAdapter
{
  public DbChangeTracker ChangeTracker { get; }
  public DbContextConfiguration Configuration { get; }
  public Database Database { get; }

  public DbEntityEntry<T> Entry<T>(T entity);
  protected virtual void OnModelCreating(DbModelBuilder modelBuilder);
  public virtual int SaveChanges();
  public DbSet<T> Set<T>();
}

DbContext implements “IDisposable” so that you can use the object in a “using” block to ensure the object is safely disposed.

Also DbContext implements “IObjectContextAdapter

public interface IObjectContextAdapter
{
  ObjectContext ObjectContext { get; }
}

By implementing the “IObjectContextAdapter” interface, DbContext provides access to the underlying ObjectContext.

 

2. Constructors

public class DbContext
{
  protected DbContext();
  public DbContext(string nameOrConnectionString); // Either the database name or a connection string
  public DbContext(DbConnection existingConnection, bool contextOwnsConnection);
  public DbContext(ObjectContext objectContext, bool dbContextOwnsObjectContext);
}

By default, the DbContext object looks up the connection string in the config file using its name and the if the connection string does not exists, try to connect to the SQL Express server in the local machine using the full class name as a DB name.

For example, suppose you have a “Mycom.Dbaccess.ProductContext” class that derived from “DbContext“. When the instance of “ProductContext” is referenced, the framework looks for the connection string with the name “ProductContext” in the “App.config” or “Web.config” file. If the connection string does not exist, the framework tries to connect to the “Mycom.Dbaccess.ProductContext” DB instance of SQL Server Express in the local machine.

If you do not want to use the local SQL Server Express as a production server (I think you do), you have 2 choices.

  • Provide the connection string with the context class name in the config file
  • If you have to use predefined connection string with the different name, you can pass the connection string name to the constructor of “DbContext

DbContext provides other constructors to accept the existing DbConnection object or even the ObjectContext objec.

If you set the “contextOwnsXXX” to true, the connection will be closed when the DbContext object is disposed. If you set this property to false, the connection will not be disposed when the context is disposed.

 

3. DbSets

The basic building blocks of DbContext is DbSet objects. If you want to keep track of Entities, each entity needs to be registered as a property of “DbContext” as the type of DbSet.

public class ProductContext : DbContext
{
  public DbSet<Product> Products { get; set; }
}

In most cases, you provide the public get property to access the DbSet directly. But in some cases, you can access the DbSet object indirectly using the “DbContext.Set<T>()” method.

ProductContext context = new ProductContext();
DbSet<Product> productSet = context.Set<Product>();

 

4. Fluent API

OnModelCreating()” method is called when the model has been initialized. You will use this method to register configurations with Fluent API.

public class ProductContext : DbContext
{
  protected overrid void OnModelCreating(DbModelBuilder modelBuilder)
  {
    // Fluent API configurations
  }
}

 

5. Persisting Changes

In order to save all changes made in this context to the underlying database, you can call the “SaveChanges()” method.

ProductContext context = new ProductContext();
context.SaveChanges();

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s