EF Core:在Migration类的Up方法中添加自定义LINQ

时间:2018-03-21 07:46:05

标签: entity-framework entity-framework-core

我想在Up方法中执行一些LINQ迁移。问题是我不知道如何获得DbContext实例?

这是migrations add生成的代码:

public partial class MyTableAddFieldTitle : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.AddColumn<string>(
            name: "Title",
            table: "MyTable",
            nullable: true);
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropColumn(
            name: "Title",
            table: "MyTable");
    }
}

我想在Up方法中添加类似内容:

protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.AddColumn<string>(
        name: "Title",
        table: "MyTable",
        nullable: true);

    var context = ?????;

    //Actual code is much more complicated, but the principle is the same.
    foreach (var item in context.Set<DbMyTable>())
      item.Title = item.SomeStringColumn;
    context.SaveChanges();
}

问题是如何获取上下文实例?我在构造函数中尝试使用DI:

protected MyTableAddFieldTitle(MyContext context)
{
}

但我收到错误:

  

MissingMethodException:没有为此定义的无参数构造函数   宾语。 System.RuntimeTypeHandle.CreateInstance(RuntimeType类型,bool   publicOnly,ref bool canBeCached,ref RuntimeMethodHandleInternal   构造函数)

1 个答案:

答案 0 :(得分:1)

我找到了解决方案。

Startup类我定义了静态变量:

public static Func<MyContext> ContextFactory;

Startup类的构造函数中,我赋予变量:

public Startup(IHostingEnvironment env, IConfiguration config)
{
    MyContext GetContext(IConfiguration configuration, IHostingEnvironment environment)
    {
        var builder = new DbContextOptionsBuilder<MyContext>();
        builder.UseSqlServer(configuration["ConnectionStrings:Web"], b => b.MigrationsAssembly("Web.Hosting"));
        if (environment.IsDevelopment())
            builder.EnableSensitiveDataLogging();
        return new MyContext(builder.Options);
    }

    ContextFactory = () => GetContext(config, env);
}

然后在迁移中,我只需致电ContextFactory

var context = Startup.ContextFactory();
context.Set<DbMyTable>().Where(....

为避免错误字段不存在,我创建了2个迁移文件(dotnet ef migrations add) 首先添加字段:

protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.AddColumn<string>(
        name: "Title",
        table: "MyTable",
        nullable: true);
}

第二个(空)执行查询:

protected override void Up(MigrationBuilder migrationBuilder)
{
    var context = Startup.ContextFactory();
    context.Set<DbMyTable>().Where(....
}