多种方式创建 Entity Framework Core 上下文
直接调用上下文无参构造函数并重载 OnConfiguring 方法;
继承自上下文基类 DbContext 并传递 DbContextOptions 到上下文构造函数中;
使用依赖注入创建上下文实例。
public class EFContext : DbContext
{
public EFContext(DbContextOptions options)
:base(options)
{
}
}
上述代码在运行时每次创建一个新的上下文实例都会调用 OnConfiguring 方法,这样我们可以通过利用 OnConfiguring 使用传递给上下文构造器或者其他实例的参数。这里需要注意的是每次调用上下文实例就必须使用 using 语句进行处理,也就是释放调用。
public class EFContext : DbContext
{
public EFContext(DbContextOptions options)
:base(options)
{
}
}
class Program
{
private static IServiceProvider serviceProvider;
static void Main(string[] args)
{
DbContextOptions context = new DbContextOptionsBuilder()
.UseSqlServer("数据库连接字符串")
.Options;
var services = new ServiceCollection()
.AddSingleton(context)
.AddScoped<EFContext>();
serviceProvider = services.BuildServiceProvider();
}
}
上述代码中并没有进行重载 OnConfiguring 方法,但是在代码运行时 OnConfiguring 会被调用和重载,这时因为在进行注入上下文的时候会调用构造函数,还会对 OnConfiguring 进行调整。
DbContext 上下文派生类可以有一个无参数的构造函数并覆盖OnConfiguring方法。这样上下文类就没有任何依赖关系,这样除了上下文类型本身之外,其他任何内容都不需要在容器中注册。
有时候需要在注入容器中注册 DbContextOptions 实例,将其注册为单例即可,这时我们只需要创建一次。下面我们以使用 DependencyInjection 为例来讲解一下,DependencyInjection 位于 Microsoft.Extensions.DependencyInjection 包中。代码如下:
public class EFContext : DbContext
{
public EFContext(DbContextOptions options)
:base(options)
{
}
}
class Program
{
private static IServiceProvider serviceProvider;
static void Main(string[] args)
{
DbContextOptions context = new DbContextOptionsBuilder()
.UseSqlServer("数据库连接字符串")
.Options;
var services = new ServiceCollection()
.AddSingleton(context)
.AddScoped<EFContext>();
serviceProvider = services.BuildServiceProvider();
}
}
上述代码中通过 serviceProvider 将上下文注入容器中,DbContextOptions 实例也被注入到了构造函数中。
有时我们需要注册多个 DbContext 上下文类,这时我们就可以使用泛型 DbContextOptions,代码如下:
class Program
{
private static IServiceProvider serviceProvider;
static void Main(string[] args)
{
DbContextOptions context1 = new DbContextOptionsBuilder()
.UseSqlServer("数据库连接字符串1")
.Options;
DbContextOptions context2 = new DbContextOptionsBuilder()
.UseSqlServer("数据库连接字符串2")
.Options;
var services = new ServiceCollection()
.AddSingleton(context1)
.AddScoped<EFContext1>()
.AddSingleton(context2)
.AddScoped<EFContext2>();
serviceProvider = services.BuildServiceProvider();
}
}
代码在运行时会按照顺序逐个注入,也是是说当代码解析到 EFContext1 时会注入 DbContextOptions<EFContext1>,解析到 EFContext2 时会注入 DbContextOptions<EFCoreDbContext2>
使用 AddDbContext 或 AddDbContextPool 注入比较简单,只需要短短的几行代码即可:
static void Main(string[] args)
{
var services = new ServiceCollection()
.AddDbContext<EFContext>(p => p.UseSqlServer("数据库连接字符串"));
}
我们将 EFCoreDbContext 注册为 Scope,并将 DbContextOptions<EFCoreDbContext> 通过委托构建为单例。委托继续使用与 OnConfiguring 中相同的 DbContextOptionsBuilder。Scope 是默认的注册类型,如果不想注册为 Scope 可以通过向 AddDbContext 传参来更高,但是要注意的是因为DbContext非线程安全,因此不可传递 Singleton。
热 文 推 荐
☞量子算命,在线掷筊:一个IBM量子云计算机的应用实践,代码都有了