在具有 EF Core 迁移的 Net Core Class 库上使用 settings.json

Use settings.json on a Net Core Class Library with EF Core migrations

在 NET Core 2.1 Class 库上我有一个 Entity Framework Core 2.1 DbContext:

public class AppContext : IdentityDbContext<User, Role, Int32> {

  public AppContext(DbContextOptions options) : base(options) { }

}

为了 运行 在 Class 库上的迁移,我需要添加以下内容:

public class ContextFactory : IDesignTimeDbContextFactory<Context> {

  public Context CreateDbContext(String[] args) {

    DbContextOptionsBuilder builder = new DbContextOptionsBuilder<Context>();

    builder.UseSqlServer(@"Server=localhost;Database=db;User=sa;Password=pass;");

    return new Context(builder.Options);

  } 

}

有了这个,我可以 运行,在 class 库命令上,如:

dotnet ef migrations add "InitialCommit"
dotnet ef database update

但是如何将连接字符串移动到 Class 库中的 settings.json 文件?

您可以在启动时配置 DbContextOptions class,然后将其注入到上下文中。在启动 class 中,您可以从配置中获取连接字符串。

Startup.cs:

  public void ConfigureServices(IServiceCollection services)
        {                        
        services.AddDbContext<Context>
        (options=> options.UseSqlServer(Configuration["ConnectionString:DefaultConnection"]));

        ....
        }

将您的连接字符串添加到 appsettings.json:

  "ConnectionString": {
    "DefaultConnection": "your connection string"
  },

IDesignTimeDbContextFactory,顾名思义,严格用于开发。通常不需要外部化连接字符串,因为它应该是非常静态的,即使在团队环境中也是如此。也就是说,如果有的话,您应该将其存储在用户机密中,因为同样,这仅用于开发。使用用户机密可使连接字符串不受您的源代码控制,因此您团队中的开发人员不会因彼此的连接字符串而踩到彼此的脚趾。

var config = new ConfigurationBuilder()
    .AddUserSecrets()
    .Build();

var connectionString = config.GetConnectionString("Foo");

IDesignTimeDbContextFactory<> 实现是 运行 通过 EF 实用程序进程。这是一个常规的控制台应用程序,您可以在其中使用 Console.Write()Console.Read() 与执行迁移和更新的用户进行交互。这允许您提示用户在更新时输入他们的连接字符串。

public class Builder : IDesignTimeDbContextFactory<AppContext>
{
    public AppContext CreateDbContext(string[] args)
    {
        Console.Write("Enter your connection string: ");
        var conStr = Console.ReadLine();

        var options = new DbContextOptionsBuilder<AppContext>().UseSqlServer(conStr).Options;

        return new AppContext(options);
    }
}