我想在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 构造函数)
答案 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(....
}