我可以安全地在ASP.NET Core和EF Core中使用非泛型DbContextOptions吗?

时间:2017-01-06 19:51:58

标签: c# asp.net-core asp.net-identity entity-framework-core

在ASP.NET Core中,EF Core上下文由内置DI容器创建。在official documentation中,使用通用DbContextOptions<TContext>创建上下文:

public class MyContext : IdentityDbContext<User> {
  public MyContext(DbContextOptions<MyContext> options, ILogger<MyContext) logger) : base(options) { }
}

但是,也有非泛型的例子:

public class MyContext : IdentityDbContext<User> {
  public MyContext(DbContextOptions options, ILogger<MyContext) logger) : base(options) { }
}

根据源代码,它们之间的区别是:

  

类型参数:TContext:这些选项适用的上下文类型。

我想使用非泛型类型,因为在我的设计中我有一个抽象的上下文,并且不能很好地与DI容器配合使用。

所以,如果我使用非泛型类型,这究竟意味着什么?我的上下文未能正确配置?

2 个答案:

答案 0 :(得分:3)

以下是基础IdentityDbContext类的签名(通用和非通用)constructor

public IdentityDbContext(DbContextOptions options)

对我来说意味着它可以毫无问题地使用非通用DbContextOptions

实际上,DbContextOptions类的genericnon generic版本之间的唯一区别是通用版本实现了abstract非泛型版本。

但是,将DbContextOptions<YourDbContext>传递给YourDbContext构造函数更安全,因为它可以确保调用者传递抽象类的正确实现(基本上是ContextType属性)。

答案 1 :(得分:3)

  

我想使用非泛型类型,因为在我的设计中我有一个抽象的上下文,并且不能很好地与DI容器配合使用。

使用DI容器可以正常播放。它只查看派生最多的类型,它试图实例化的类型。事实上,介于两者之间的基类是不相关的。

请注意,虽然您无法使用DbContextOptions<AbstractDbContext>,但您不需要。您可以使基类采用DbContextOptions,也可以使基类通用并采用DbContextOptions<ConcreteDbContext>

abstract class AbstractDbContext : DbContext
{
    protected AbstractDbContext(DbContextOptions options) : base(options)
    {
    }
}

class ConcreteDbContext : AbstractDbContext
{
    public ConcreteDbContext(DbContextOptions<ConcreteDbContext> options) : base(options)
    {
    }
}

abstract class AbstractDbContext<TContext> : DbContext
    where TContext : AbstractDbContext<TContext>
{
    protected AbstractDbContext(DbContextOptions<TContext> options) : base(options)
    {
    }
}

class ConcreteDbContext : AbstractDbContext<ConcreteDbContext>
{
    public ConcreteDbContext(DbContextOptions<ConcreteDbContext> options) : base(options)
    {
    }
}
  

所以,如果我使用非泛型类型,这究竟意味着什么?我的背景未能正确配置?

采用非泛型DbContextOptions的构造函数通常也可以。通常情况下,您是对的,服务提供商无法解决这个问题。但是,当您致电serviceCollection.AddDbContext<ConcreteDbContext>(...)时,EF Core会专门通知服务容器,当请求DbContextOptions实例时,应提供DbContextOptions<ConcreteDbContext>实例。

请注意,这仅适用于您具有单个上下文类型的情况。如果您有多个,服务提供商没有足够的信息来确定您需要的信息。