如何在 ASP.NET Core 2.0 和 EF Core 2.0 中将应用程序设置从项目根获取到 IDesignTimeDbContextFactory 实现

V. *_*mma 6 asp.net entity-framework entity-framework-core asp.net-core-2.0 ef-core-2.0

我正在 ASP.NET Core 2.0 中构建应用程序,但在 EntityFramework 迁移方面遇到问题。

我的 DbContext 位于一个单独的项目 ( SolutionName \ ProjectNamePrefix .Data) 中,因此我创建了 IDesignTimeDbContextFactory 接口的实现。

我想为不同的环境使用不同的连接字符串,并且我需appsettings.json要这样做。

因此,经过快速搜索后,我发现我可以在函数IConfigurationRoot内创建一个新对象CreateDbContext,如下所示: https: //codingblast.com/entityframework-core-idesigntimedbcontextfactory/

dotnet ef migrations list -c MyContext我添加了它,然后为了测试,尝试从数据项目根文件夹运行。

然后我收到以下错误:

The configuration file 'appsettings.json' was not found and is not optional. The physical path is 'C:\dev\*SolutionName*\*ProjectNamePrefix*.Data\bin\Debug\netcoreapp2.0\appsettings.json'.
Run Code Online (Sandbox Code Playgroud)

所以,基本上,我尝试了 3 个选项来获取正确的根路径:

  • Directory.GetCurrentDirectory();
  • env.ContentRootPath;IHostingEnvironment对象,我找到了一种方法来获取它: https: //github.com/aspnet/Home/issues/2194
  • AppDomain.CurrentDomain.BaseDirectory;

他们都返回同一..\bin\debug\netcoreapp2.0\条路。当我从 VS 运行数据项目时,前两个选项为我提供了正确的项目根文件夹。

有没有办法获取正确的项目内容根文件夹?

因为当我向 EF 命令添加 --verbose 时,它​​会注销一行:

Using content root 'C:\dev\FitsMeIdentity\FitsMeIdentity.Data\'.
Run Code Online (Sandbox Code Playgroud)

所以我知道 EF 以某种方式知道项目根目录,但上面提到的所有选项都会返回已构建的应用程序的路径。

我发现有效的唯一选择是我更改Copy output to root folderCopy always但从这里找到: https: //www.benday.com/2017/02/17/ef-core-migrations-without-hard-coding-a-connection-string -using-idbcontextfactory/这不是一个好主意。

起初,我什至考虑过为 IDesignTimeDbContextFactory 实现创建一个构造函数,它获取 IOptions 作为参数,但这不起作用,遇到了与此处解释的相同的问题: Injecting Env Conn String into .NET Core 2.0 w/EF Core DbContext in different类库比 Startup prj 和实现 IDesignTimeDbContextFactory

Sea*_*urn 14

有点晚了,但对于那些讨厌硬编码连接字符串的人来说,这是解决方案:

internal class MigrationDbContextFactory : IDesignTimeDbContextFactory<AppDbContext>
{
    public AppDbContext CreateDbContext(string[] args)
    {
        IConfigurationRoot configuration = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json", false)
            .Build();
        
        string connectionString = configuration.GetConnectionString("DefaultConnection");

        DbContextOptionsBuilder<AppDbContext> optionsBuilder = new DbContextOptionsBuilder<AppDbContext>();
        optionsBuilder.UseMySql(connectionString,
            ServerVersion.AutoDetect(connectionString),
            mySqlOptions =>
                mySqlOptions.EnableRetryOnFailure(
                    maxRetryCount: 10,
                    maxRetryDelay: TimeSpan.FromSeconds(30),
                    errorNumbersToAdd: null));

        return new AppDbContext(optionsBuilder.Options);
    }
}
Run Code Online (Sandbox Code Playgroud)


Chr*_*att 2

不。你不能这样做,更重要的是:你不应该这样做。整个要点是,它是一种从没有 ASP.NET Core 框架可使用的上下文(即从类库)IDesignTimeDbContextFactory获取实例的方法。DbContext如果您正在从 ASP.NET Core 项目运行迁移,则不需要它,如果不需要,则没有任何配置内容可用。

此外,它仅用于开发,因此名称中包含“DesignTime”部分。因此,不需要像在不同环境的连接字符串之间进行切换之类的事情。只需按照文档详细信息对连接字符串进行硬编码即可。