既存のモデルに新しいプロパティを追加しました。これは、デフォルト値がtrueのboolプロパティです。このテーブルには既存のデータがあり、Upメソッドで新しいフィールドを作成した直後に、特定の行の新しいプロパティをfalseに設定したいと思います。
public override void Up()
{
AddColumn("dbo.RequestValidationErrors", "IsBreaking", c => c.Boolean(nullable: false));
using (Context ctx = new Context())
{
var validation = ctx.RequestValidationErrorSet.FirstOrDefault(x => x.WordCode == "RequestValidationError.MoreThanOneItemFound");
if (validation != null)
{
validation.IsBreaking = false;
ctx.SaveChanges();
}
}
}
このようにして、EFは発言中にエラーをスローします
System.InvalidOperationException: 'DbContext'コンテキストをサポートするモデルは、データベースが作成されてから変更されました。 Code First Migrationsを使用してデータベースを更新することを検討してください
ここでデータベースを変更することは可能ですか、それとも別の場所で行う必要がありますか?
移行の途中では、Sql()
メソッドを使用してデータベースデータを更新することをお勧めします。
Sql("UPDATE dbo.RequestValidationErrors SET IsBreaking = 0 WHERE WordCode = 'RequestValidationError.MoreThanOneItemFound'");
また、新しい列のデフォルト値を定義する必要があります。そのため、解決策は次のようになります。
public override void Up()
{
AddColumn("dbo.RequestValidationErrors", "IsBreaking", c => c.Boolean(nullable: false, default: true));
Sql("UPDATE dbo.RequestValidationErrors SET IsBreaking = 0 WHERE WordCode = \"RequestValidationError.MoreThanOneItemFound\"");
}
移行の途中でDbContext
を使用することは非常にあいまいです。コンテキストに何を期待しますか?モデルには移行後がありますが、データベースにはテーブルに移行前があります。そのため、モデルとデータベースは一致しません。それでもコードでDbContext
を使用することを主張する場合は、モデルチェックを無効にすることが解決策になる可能性があります。以下を使用してモデル検査を無効にできます。
Database.SetInitializer<Log4ProContext>(null);
このような変更にフレームワークを使用する場合は、データベースの変更をデータの変更から分離する必要があります。
データベースの変更のみの移行を作成し、実行します。
次に、新しい移行を作成します(Up()およびDown()メソッドは空になります)。これでDatabaseContextをインスタンス化でき、エラーは発生しません。このようにして、これらの変更にフレームワークを使用し、Down()メソッドを適切に実装できます。
Sql
メソッドを使用する代わりに、 UpdateData
メソッドを使用することもできます。
migrationBuilder.UpdateData(
table: "RequestValidationErrors",
keyColumn: "WordCode",
keyValue: "RequestValidationError.MoreThanOneItemFound",
column: "IsBreaking",
value: false);
(efコアのみがこのメソッドをサポートしているかどうかわかりません)
EF6用のDataMigrationsの作成は面倒な作業です。私たちは、ここで他の人が使用できるようにオープンソース化したライブラリをまとめました。通常のEFクエリなどを使用してクラスを記述するだけです。