Asp.net core mvc 在实现DbContextPooling和代码优先数据库迁移时使用上下文构造函数

Asp.net core mvc 在实现DbContextPooling和代码优先数据库迁移时使用上下文构造函数,asp.net-core-mvc,ef-code-first,dbcontext,asp.net-core-2.1,Asp.net Core Mvc,Ef Code First,Dbcontext,Asp.net Core 2.1,首先,我为这篇文章的标题道歉。我真的不知道该如何形容它 在我们的一个MVC项目中,我们使用自定义上下文使用AddDbContextPool,该上下文有一个构造函数,该构造函数接受DbContextOptions的单个参数。当像这样的上下文中只有一个构造函数时,所有这些都非常有效 然而,为了进行DB迁移,它需要上下文中的空构造函数(据我所知) 如果我将其放回上下文中,则我的MVC项目开始接收: “DbContext”类型的DbContext不能被池化,因为它没有 让一个公共构造函数接受一个类型为的

首先,我为这篇文章的标题道歉。我真的不知道该如何形容它

在我们的一个MVC项目中,我们使用自定义上下文使用AddDbContextPool,该上下文有一个构造函数,该构造函数接受DbContextOptions的单个参数。当像这样的上下文中只有一个构造函数时,所有这些都非常有效

然而,为了进行DB迁移,它需要上下文中的空构造函数(据我所知)

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

“DbContext”类型的DbContext不能被池化,因为它没有 让一个公共构造函数接受一个类型为的参数 DbContextOptions

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

那么,有没有人知道一种方法可以让大家友好相处?如何使用一个自定义上下文进行迁移,该上下文只有一个构造函数接受DbContextOptions类型的参数?或者,如何在保持DbContextPool工作的同时拥有多个构造函数

然而,为了进行DB迁移,它需要上下文中的空构造函数(据我所知)

这是不正确的。空构造函数不是必需的,也不应存在。我想了解一下正在发生的事情会有助于你理解

EF核心是为依赖注入而设计的。If期望通过依赖项注入提供
DbContextOptions
。但是,当从命令行运行命令时,您的应用程序可能没有运行,即使它运行了,也确实无法以某种方式远程访问其服务集合以获取必要的信息。因此,EF Core通过以下两种方式之一进行补偿:

  • 如果运行命令所针对的项目是一个启动项目(它实际上不需要是启动项目-只是一个可以启动的项目),那么EF将实际运行
    程序
    ,以访问该服务集合,从那里拉出
    DbContext
    ,正如任何其他正常的
    DbContext
    注入都可以工作一样

  • 但是,如果项目类似于类库,那么它就不能这样做。在这种情况下,除了要迁移的项目之外,还可以向它传递一个要使用的启动项目。如果您这样做,它的工作原理与上面的#1基本相同。除此之外,它还需要其他方法来知道该做什么

  • 这就把我们带到了另一个方向。有一个名为
    IDesignTimeDbContextFactory
    的接口。如果该接口的实现存在于正在迁移的项目EF Core中,那么它将使用该接口获取其上下文。典型的实现如下所示:

    public class MyDbContextFactory : IDesignTimeDbContextFactory<MyDbContext>
    {
        public MyDbContext CreateDbContext(string[] args)
        {
            var options = new DbContextOptionsBuilder<MyDbContext>()
                .UseSqlServer("[connection string here]")
                .Options;
    
            return new MyDbContext(options);
        }
    }
    
    公共类MyDbContextFactory:IDesignTimeDbContextFactory
    {
    公共MyDbContext CreateDbContext(字符串[]args)
    {
    var options=new DbContextOptionsBuilder()
    .UseSqlServer(“[此处连接字符串]”)
    .选择;
    返回新的MyDbContext(选项);
    }
    }
    
    旁白

    连接字符串的大部分应为硬编码。人们往往会有点疯狂,试图建立一个完整的并行配置设置,这在很大程度上是不必要的。正如接口的名称所示,这是为了开发。此实现不应该在任何其他环境中运行,因此没有理由使用特定于环境的设置。此外,开发连接字符串通常可以由开发人员以特定的方式构造,因此通常不需要从一个开发人员更改到下一个开发人员。如果确实需要,只需加载User Secrets配置提供程序,就可以让各个开发人员从中定义他们的个人连接字符串