在实现DbContextPooling和代码优先Db迁移时的上下文构造函数

时间:2019-07-02 15:59:24

标签: asp.net-core-mvc ef-code-first dbcontext asp.net-core-2.1

首先,我为此头条表示歉意。我不确定如何描述它。

在我们的一个MVC项目中,我们使用AddDbContextPool并使用我们的自定义上下文,该上下文具有一个带有单个参数DbContextOptions的构造函数。当在这样的上下文中只有一个构造函数时,所有方法都很好用。

但是,为了进行数据库迁移,它需要在上下文中有一个空的构造函数(据我所知)。

如果我将其放回上下文中,则我的MVC项目开始接收:

  

'DbContext'类型的DbContext无法合并,因为它没有   有一个公共构造函数,它接受一个类型的参数   DbContextOptions

如果上下文中没有空构造函数,则无法生成新的数据库迁移。

那么,有谁知道一种让这一切彼此和谐相处的方法?如何使用具有单个构造函数且参数类型为DbContextOptions的自定义上下文进行迁移?还是在保持DbContextPooling工作的同时如何拥有多个构造函数?

1 个答案:

答案 0 :(得分:0)

  

但是,为了进行数据库迁移,它需要在上下文中有一个空的构造函数(据我所知)。

那是不正确的。一个空的构造函数不是必需的,也不应该存在。我认为了解正在发生的事情将有助于您理解。

EF Core设计用于依赖项注入。如果期望DbContextOptions通过依赖项注入提供。但是,从命令行运行命令时,您的应用程序可能未运行,即使运行了,实际上也无法以某种方式远程进入其服务集合以获取必要的信息。结果,EF Core补偿了以下两种方式之一:

  1. 如果要运行命令的项目是一个启动项目(实际上并不需要是 启动项目,只需一个可以启动),那么EF实际上将运行Program来访问该服务集合,将DbContext从那里拉出,就像其他任何正常注入DbContext一样。

  2. 但是,如果项目类似于类库,则无法做到这一点。在这种情况下,除了要迁移的项目外,还可以将启动项目传递给它使用。如果执行此操作,则其工作原理与上述#1基本相同。除此之外,还需要其他方法来知道该怎么做...

这将我们带入了另一种方式。有一个名为IDesignTimeDbContextFactory的接口。如果要迁移的项目中存在该接口的实现,那么它将使用该接口来获取其上下文。一个典型的实现如下所示:

public class MyDbContextFactory : IDesignTimeDbContextFactory<MyDbContext>
{
    public MyDbContext CreateDbContext(string[] args)
    {
        var options = new DbContextOptionsBuilder<MyDbContext>()
            .UseSqlServer("[connection string here]")
            .Options;

        return new MyDbContext(options);
    }
}

在旁边

在大多数情况下,连接字符串应采用硬编码。人们在这里往往会有些疯狂,并尝试建立一个完整的并行配置设置,这在很大程度上是不必要的。就像接口的名称所示,这是为了开发。此实现不应在任何其他环境中运行,因此没有理由进行特定于环境的设置。另外,开发连接字符串通常可以以开发者专用的方式构造,因此通常不必从一个开发者更改为下一个开发者。如果需要,则只需加载“用户密码”配置提供程序,以允许各个开发人员从此处定义其个人连接字符串。