构造函数注入IDesignTimeDbContextFactory

时间:2017-10-05 13:43:12

标签: entity-framework entity-framework-core

我试图在.NET标准2.0 类库中使用迁移EFCore2.0,到目前为止,我有类似的内容

public class SomeContextFactory : IDesignTimeDbContextFactory<SomeContext>
{
    private Configuration _configuration;

    public SomeContextFactory(Configuration configuration)
    {
        _configuration = configuration;
    }

    public SomeContext CreateDbContext(string[] args)
    {
        var optionsBuilder = new DbContextOptionsBuilder<SomeContext>();

        optionsBuilder.UseSqlServer(_configuration.ConnectionString);

        return new SomeContext(optionsBuilder.Options);
    }
}

public class SomeContext : DbContext
{
    public DbSet<SomeDbModel> Some { get; set; }

    public SomeContext(DbContextOptions<SomeContext> options) : base(options)
    {
    }
}

关键是连接字符串因环境(dev,test,prod)而异,并且应该对Configuration指定的数据库执行迁移。

如何指示迁移将Configuration注入SomeContextFactory

2 个答案:

答案 0 :(得分:0)

By designIDesignTimeDbContextFactory不支持与DI一起使用。 实现此would be的一种方法:

public class AppDbContextFactory : IDesignTimeDbContextFactory<AppDbContext>
{
  public AppDbContext CreateDbContext(params string[] args)
  {
    var options = new DbContextOptionsBuilder<AppDbContext>();
    var config = GetAppConfiguration();
    options.UseSqlServer(config.GetConnectionString("DesignTimeAppDbConnection"));

    return new AppDbContext(options.Options);
  }

  IConfiguration GetAppConfiguration()
  {
    var environmentName =
              Environment.GetEnvironmentVariable(
                  "ASPNETCORE_ENVIRONMENT");

    var dir = Directory.GetParent(AppContext.BaseDirectory);      

    if(EnvironmentName.Development.Equals(environmentName, 
        StringComparison.OrdinalIgnoreCase))
    {                  
      var depth = 0;
      do
        dir = dir.Parent;
      while (++depth < 5 && dir.Name != "bin");
      dir = dir.Parent;
    }

    var path = dir.FullName;

    var builder = new ConfigurationBuilder()
            .SetBasePath(path)
            .AddJsonFile("appsettings.json")
            .AddJsonFile($"appsettings.{environmentName}.json", true)
            .AddEnvironmentVariables();

    return builder.Build();
  }
}

答案 1 :(得分:-1)

在Startup.cs

services.AddTransient<SomeContextFactory>();

和你的工厂:

public class SomeContextFactory : 
IDesignTimeDbContextFactory<SomeContext>
{
    private readonly IHostingEnvironment environment;
    private readonly IConfigurationRoot config;

    public SomeContextFactory(IConfigurationRoot config, 
IHostingEnvironment environment)
    {
        this.environment = environment;
        this.config = config;
    }

    public SomeContext CreateDbContext()
    {
        return CreateDbContext(null);
    }

    public SomeContext CreateDbContext(string[] args)
    {
        var builder = new DbContextOptionsBuilder<SomeContext>();
        var connectionString = config.GetConnectionString("Default");

        builder.UseSqlServer(connectionString);

        return new SomeContext(builder.Options);
    }
}