具有配置的类库中的实体框架7迁移支架

Cud*_*nny 11 ef-migrations entity-framework-core visual-studio-2015 dnx asp.net-core

尝试将迁移添加到位于ASP.NET 5类库中的EF7模型.当运行dnx . ef migration add mymigration失败时会有不同的结果,具体取决于我运行它的项目.

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

如果我在共享项目的文件夹中运行它,它就无法访问startup.cs中指定的连接字符串.我从这样的问题收集是它从共享的项目工作,如果你指定要在连接字符串OnConfiguring的方法DbContext,但我真的想保持这个代码从配置独立.

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

Sha*_*tin 10

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

如果我在共享项目的文件夹中运行它,它就无法访问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!");
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

config.json

此外,我假设您正在将连接字符串添加到项目根目录中的config.json(或者您通过用户机密或环境变量添加它.)您的config.json可能如下所示:

{
  "ConnectionStrings": {
    "MyDbContext": "Some-Connection-String"
  }
}
Run Code Online (Sandbox Code Playgroud)

如果你不是这样做的话,可能值得尝试.

我从这样的问题中收集到,如果你在DbContext的OnConfiguring方法中指定了连接字符串,它确实可以在共享项目中工作,但我真的希望将这些代码与配置分开.

的DbContext

如果我的上述假设是正确的,那么您可以DbContext使用您在Startup类中使用的相同模式来访问连接字符串.也就是说,在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;
    }
}
Run Code Online (Sandbox Code Playgroud)

项目结构

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

SharedDataContext
    Migrations
    config.json
    project.json

WebApp
    config.json
    project.json
    Startup.cs
Run Code Online (Sandbox Code Playgroud)

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

一些想法

如果您不喜欢复制config.json连接字符串,那么您可以使用环境变量或用户机密.

  • @ShaunLuttin和beta5他们改变了Config接口以要求一个基本路径,我通常会从IApplicationEnvironment.ApplicationBasePath获得.问题是,当我将IApplicationEnvironment添加到构造函数时,我得到一个错误,即当我运行"ef migration add"时没有默认构造函数.我想知道硬编码路径或连接字符串是否会如此糟糕.这一切都非常hacky和不幸但是:(谁会把他们的背景放在与web相同的项目中?为什么这样的疏忽? (3认同)