Entity Framework Class 库中的 7 个迁移脚手架与配置

Entity Framework 7 Migration Scaffolding in Class Library with Configuration

正在尝试将迁移添加到 ASP.NET 5 class 库中的 EF7 模型。当 运行ning dnx . ef migration add mymigration 失败时,根据我 运行 它所在的项目,结果会有所不同。

如果我 运行 它在主项目的文件夹中,它找不到 DbContext,这是有道理的,因为 DbContext 在共享项目中并且 ef 命令可能不关心依赖关系。

如果我 运行 它在共享项目的文件夹中,它无权访问 startup.cs 中指定的连接字符串。我从 之类的问题中了解到,如果您在 DbContextOnConfiguring 方法中指定连接字符串,它确实可以从共享项目中工作,但我真的很想将这段代码分开来自配置。

我在 EF7 存储库中遇到了一些 issue logs,提到他们实现了用于指定项目和上下文的命令行选项,但没有示例,我无法通过查看来弄清楚如何使用它在提交历史中的源代码处。

这是一种可能适合您的方法。

If I run it in the folder of the shared project, it does not have access to the connection string specified in the startup.cs.

Startup.cs

我假设在您的 Startup.cs 中,您是通过访问 Configuration 而不是通过硬编码来指定连接字符串。此外,我假设在 Startup.cs 文件的构造函数中,您正在从几个来源设置配置。换句话说,您的 Startup.cs 可能看起来像这样:

public class Startup
{
    public IConfiguration Config { get; set; }

    public Startup(IHostingEnvironment env)
    {
        var config = new Configuration()
            .AddJsonFile("config.json")
            .AddUserSecrets()
            .AddEnvironmentVariables();

        Config = config;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddEntityFramework()
            .AddSqlServer()
            .AddDbContext<MyDbContext>(options =>
            {
                options.UseSqlServer(Config["ConnectionStrings:MyDbContext"]);
            });
    }

    public void Configure(IApplicationBuilder app, IServiceProvider serviceProvider)
    {
        var db = serviceProvider.GetRequiredService<MyDbContext>();
        db.Database.AsSqlServer().EnsureCreated();

        app.Run(async (context) =>
        {
            await context.Response.WriteAsync("Hello World!");
        });
    }
}

config.json

此外,我假设您将连接字符串添加到项目根目录中的 config.json(或者您通过用户机密或环境变量添加它。)您的 config.json 可能看起来像这样:

{
  "ConnectionStrings": {
    "MyDbContext": "Some-Connection-String"
  }
}

如果您不这样做,可能值得一试。

I have gleaned from questions like this that it does work from the shared project if you specify the connection string in the OnConfiguring method of the DbContext but I really would like to keep this code separate from the configuration.

DbContext

如果我上面的假设是正确的,那么您可以使用在 Startup class 中使用的相同模式访问 DbContext 中的连接字符串。也就是说,在 DbContext 构造函数中,设置 IConfiguration。然后,在 OnConfiguring 中访问连接字符串。它可能看起来像这样:

public class MyDbContext : DbContext
{
    protected override void OnModelCreating(ModelBuilder builder)
    {
        builder.Entity<SomeModel>().Key(e => e.Id);
        base.OnModelCreating(builder);
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        var connString = Config["ConnectionStrings:MyDbContext"];
        optionsBuilder.UseSqlServer(connString);
    }

    public IConfiguration Config { get; set; }

    public MyDbContext()
    {
        var config = new Configuration()
            .AddJsonFile("config.json")
            .AddEnvironmentVariables();

        Config = config;
    }
}

项目结构

您当然还需要在共享项目文件夹的根目录中有一个 config.json 文件。因此,您的项目结构可能如下所示:

SharedDataContext
    Migrations
    config.json
    project.json

WebApp
    config.json
    project.json
    Startup.cs

在上面,两个 config.json 文件都包含 DbContext 的连接字符串设置。

一些想法

如果您不喜欢复制 config.json 连接字符串内容,则可以改用环境变量或用户机密。