EF6 と EF Core の間の動作変更

これは、EF6 と EF Core の間での動作に関する変更点の一覧です (網羅されてはいません)。 アプリケーションを移植する際に、これらの点に注意することが重要です。これらによってアプリケーションの動作方法が変更される可能性がありますが、EF Core へのスワップ後にコンパイル エラーとして表示されることはありません。

これは、移植プロセスの一環として考慮する概要レベルのレビューを示すものです。 詳細なケースバイケースの手順については、詳細なケースを参照してください。

DbSet.Add/Attach とグラフの動作

EF6 では、エンティティに対して DbSet.Add() を呼び出すと、そのナビゲーション プロパティで参照されているすべてのエンティティに対して再帰的な検索が実行されます。 見つかったすべてのエンティティと、まだコンテキストによって追跡されていないエンティティも、追加済みとしてマークされます。 DbSet.Attach() の動作は、すべてのエンティティが変更なしとしてマークされる以外は同じです。

EF Core でも同様の再帰的な検索が実行されますが、若干異なる規則がいくつか使われます。

  • 生成されたキーに対してルート エンティティが構成されていて、キーが設定されていない場合は、Added 状態になります。
  • ナビゲーション プロパティの再帰的な検索中に検出されたエンティティの場合:
    • エンティティの主キーがストアで生成されたものだった場合
      • 主キーが値に設定されていない場合、状態は追加済みに設定されます。 主キーに対してそのプロパティの型の CLR 既定値 (たとえば、int に対して 0string に対して null など) が割り当てられていた場合、それは "未設定" と見なされます。
      • 主キーが値に設定されていた場合、その状態は変更なしに設定されます。
    • 主キーがデータベースで生成されたものではなかった場合、そのエンティティはルートと同じ状態になります。
  • この動作の変更は、Attach および Update メソッド グループにのみ適用されます。 Add は、キーが設定されている場合でも、エンティティを常に Added 状態にします。
  • Attach メソッドは、キーが設定されたエンティティを Unchanged 状態にします。 これにより、"新しい場合は挿入し、それ以外の場合はそのままにする" Update メソッドは、キーが設定されたエンティティを Modified 状態にします。 これにより、"新しい場合は挿入し、それ以外の場合は更新する" のが容易になります。

ここでの一般的な考え方として、Update は、切断されたエンティティの挿入と更新を処理する非常に簡単な方法です。 これにより、新しいエンティティは挿入され、既存のエンティティは更新されます。

同時に、Add はエンティティを強制的に挿入する簡単な方法を提供します。 Add は、ストアで生成されたキーを使用しないためにエンティティが新しいかどうかを EF が認識しないときにのみ最も役立ちます。

EF Core でのこれらの動作の詳細については、「EF Core での変更の追跡」を参照してください。

Code First のデータベース初期化

EF6 には、データベース接続の選択やデータベースの初期化に関連して実行される魔法が大量に含まれています。 たとえば、次のような規則があります。

  • 構成が実行されない場合、EF6 により SQL Express または LocalDb のデータベースが選択されます。
  • コンテキストと同じ名前の接続文字列がアプリケーションの App/Web.config ファイル内にある場合は、この接続が使用されます。
  • データベースが存在しない場合は、作成されます。
  • モデルのテーブルがデータベース内に 1 つも存在しない場合は、現在のモデルのスキーマがデータベースに追加されます。 移行が有効になっている場合、データベースを作成するためにそれらが使用されます。
  • データベースが存在し、EF6 によって既にスキーマが作成されていた場合は、スキーマに現在のモデルとの互換性があるかどうかがチェックされます。 スキーマの作成後にモデルが変更されていた場合は、例外がスローされます。

EF Core では、このような魔法は実行されません。

  • データベース接続は、コード内で明示的に構成する必要があります。
  • 初期化は実行されません。 DbContext.Database.Migrate() を使って移行を適用する必要があります (または、DbContext.Database.EnsureCreated() および EnsureDeleted() を使って、移行を使わずにデータベースの作成/削除を行います)。

Code First のテーブルの名前付け規則

EF6 では、エンティティ クラス名を複数形化サービスにかけて、そのエンティティがマップされる既定のテーブル名を計算します。

EF Core では、派生コンテキストでエンティティが公開される DbSet プロパティの名前が使われます。 エンティティに DbSet プロパティがない場合は、クラス名が使われます。

詳細については、「データベース スキーマを管理する」を参照してください。