質問: .NET Core、EF Core、Postgresを使用して新しいアプリケーションを開始しています-移行が本当に好きです:-) しかし、回避方法を理解できない問題が見つかりました。一部の移行では、 `DbContext`を使用して`DbContext`を読み込み、ビジネスロジックを実行し、レコードを再保存します。また、Webサーバーの起動時に`database.Context.Migrate()`実行するため、常に実行されます。 これはすべて正常に機能します(これまで)。 残念ながら、後の時点でモデルが変更されるまで機能します。次の移行順序を考慮してください。 1. `Customer` 、 `Order` 、および`OrderLine`モデルを作成します。スキーマ移行を追加して、構造をロードします 2. ビジネスルールが変更されるため、ビジネスロジックに基づいて`Order`レコードに値を設定する必要があります。 `DbContext`をロードしてコードを実行し、 `SaveChangesAsync()`を実行するデータ移行を作成します この時点で、すべてが正常です。 3. 新しいフィールドを持つスキーマ移行を`Customer`レコードに追加する必要があります。 ここで、物事は壊れます。データベースに移行2が適用されていない場合、 `Migrate()`コマンドは移行2を適用するときにエラーが発生します。EFは3の新しいフィールドを含むselectステートメントを生成しようとします。 しかし、問題が実際にプロセスのどこにあるのかわかりません:移行で`DbContext`を使用しないでください(およびSQLステートメントを手動でコーディングする必要があります)?何をしているかを正確に把握するために、読み取ったすべてのレコードに対して明示的に投影を行う必要がありますか? 他に何か?
回答: この例では、1と3はスキーマの移行であり、2はデータの移行です。 Entity Framework Coreは、データベースの現在の状態ではなく、コード内の現在のモデルに基づいてクエリを生成するため、データ移行を処理するための2つのオプションがあります。 1. **スキーマ移行を使用してデータ移行を順序どおりに実行する** DapperやADO.NETなどを使用して、移行が作成された時点のスキーマに基づいてデータ移行を実行します。 `context.Database.GetDbConnection()`を使用して、EFコンテキストから`DbConnection`オブジェクトを取得できます。 *長所:*移行コードを変更する必要はありません *短所:* EF Coreの利点は得られません 2. **スキーマの移行後にデータの移行を実行する** EFは、 `MigrationAttribute.Id`文字列値の昇順で移行を実行します。 EFは、 `dotnet ef migrations add xxx`呼び出すときにタイムスタンプに基づいてこれを生成します。この属性を変更して、すべてのスキーマ移行後にデータ移行が実行されるようにすることができます。読みやすいようにファイル名も変更して、適用される順序のままにしてください。 *長所:* EF Coreのすべての利点が得られます *短所:*データ移行で参照されている列を削除するなど、スキーマが将来変更される場合は、移行を変更する必要があります `MigrationAttribute.Id`変更例: ``` // change [Migration("20191002171530_DataMigration")] // to [Migration("99999999000001_DataMigration")] ```