Caution
This documentation is for EF Core. For EF6.x and earlier release see http://msdn.com/data/ef.
Configuring a DbContext¶
This article shows patterns for configuring a DbContext
with
DbContextOptions
. Options are primarily used to select and configure the
data store.
In this article
Configuring DbContextOptions¶
DbContext
must have an instance of DbContextOptions
in order to execute. This can be
supplied to DbContext
in one of two ways.
If both are used, “OnConfiguring” takes higher priority, which means it can overwrite or change options supplied by the constructor argument.
Constructor argument¶
public class BloggingContext : DbContext
{
public BloggingContext(DbContextOptions<BloggingContext> options)
: base(options)
{ }
public DbSet<Blog> Blogs { get; set; }
}
Tip
The base constructor of DbContext also accepts the non-generic version of DbContextOptions
. Using the non-generic version is not recommended for applications with multiple context types.
var optionsBuilder = new DbContextOptionsBuilder<BloggingContext>();
optionsBuilder.UseSqlite("Filename=./blog.db");
using (var context = new BloggingContext(optionsBuilder.Options))
{
// do stuff
}
OnConfiguring¶
Caution
OnConfiguring
occurs last and can overwrite options obtained from DI or
the constructor. This approach does not lend itself to testing (unless you
target the full database).
public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite("Filename=./blog.db");
}
}
using (var context = new BloggingContext())
{
// do stuff
}
Using DbContext with dependency injection¶
EF supports using DbContext
with a dependency injection container. Your DbContext type can
be added to the service container by using AddDbContext<TContext>
.
AddDbContext
will add make both your DbContext type, TContext
, and DbContextOptions<TContext>
to the available for injection from the service container.
See more reading below for information on dependency injection.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<BloggingContext>(options => options.UseSqlite("Filename=./blog.db"));
}
This requires adding a constructor argument to you DbContext type that accepts DbContextOptions
.
public class BloggingContext : DbContext
{
public BloggingContext(DbContextOptions<BloggingContext> options)
:base(options)
{ }
public DbSet<Blog> Blogs { get; set; }
}
public MyController(BloggingContext context)
using (var context = serviceProvider.GetService<BloggingContext>())
{
// do stuff
}
var options = serviceProvider.GetService<DbContextOptions<BloggingContext>>();
Using IDbContextFactory<TContext>
¶
As an alternative to the options above, you may also provide an implementation of IDbContextFactory<TContext>
.
EF command line tools and dependency injection can use this factory to create an instance of your DbContext. This may be required in order to enable specific design-time experiences such as migrations.
Implement this interface to enable design-time services for context types that do not have a public default constructor. Design-time services will automatically discover implementations of this interface that are in the same assembly as the derived context.
Example:
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
namespace MyProject
{
public class BloggingContextFactory : IDbContextFactory<BloggingContext>
{
public BloggingContext Create()
{
var optionsBuilder = new DbContextOptionsBuilder<BloggingContext>();
optionsBuilder.UseSqlite("Filename=./blog.db");
return new BloggingContext(optionsBuilder.Options);
}
}
}
More reading¶
- Read Getting Started on ASP.NET Core for more information on using EF with ASP.NET Core.
- Read Dependency Injection to learn more about using DI.
- Read Testing with InMemory for more information.
- Read Understanding EF Services for more details on how EF uses dependency injection internally.