EF6 から EF Core への移植に関する詳細なケース

このドキュメントでは、EF6 と EF Core のいくつかの具体的な違いについて詳しく説明します。 コードを移植するときは、このガイドを参照してください。

データベース接続の構成

EF6 がさまざまなデータ ソースに接続する方法には、EF Core と比較して、いくつかの違いがあります。 コードを移植する際にこれらを理解しておくことが重要です。

  • 接続文字列: EF Core では、EF6 のように異なる接続文字列に対する複数のコンストラクター オーバーロードが直接サポートされていません。 代わりに、DbContextOptions に依存します。 派生型では複数のコンストラクター オーバーロードを指定できますが、オプションを使って接続をマップする必要があります。
  • 構成とキャッシュの: EF Core では、外部サービス プロバイダーに接続できる内部インフラストラクチャを使った、より堅牢かつ柔軟な依存関係の挿入の実装がサポートされています。 これは、キャッシュをフラッシュする必要がある状況を処理するために、アプリケーションによって管理できます。 EF6 バージョンは制限されており、フラッシュできませんでした。
  • 構成ファイル: EF6 では、プロバイダーを含めることができる構成ファイルを使った構成がサポートされています。 EF Core では、プロバイダー アセンブリへの直接参照と、明示的なプロバイダー登録 (つまり UseSqlServer) が必要です。
  • 接続ファクトリ: EF6 では接続ファクトリがサポートされていました。 EF Core では接続ファクトリがサポートされておらず、常に接続文字列が必要です。
  • ログ: 一般に、EF Core のログははるかに堅牢であり、構成を微調整するための複数のオプションがあります。

規約

EF6 では、カスタム ("簡易") 規則とモデル規則がサポートされていました。 簡易規則は、EF Core の規則の前のモデル構成に似ています。 その他の規則は、モデル構築の一部としてサポートされています。

EF6 では、モデルの構築後に規則が実行されます。 EF Core では、モデルの構築中に適用されます。 EF Core では、DbContext を使って、モデル構築をアクティブなセッションから切り離すことができます。 規則で初期化されたモデルを作成することができます。

データ検証

EF Core ではデータ検証がサポートされず、モデルの構築と移行にデータ注釈のみが使われます。 web/MVC から WinForms や WPF まで、ほとんどのクライアント ライブラリでは使用可能なデータ検証の実装が用意されています。

近日公開予定の機能

EF6 には、EF Core にはまだ存在しないが、製品ロードマップには記載されているいくつかの機能があります。

  • table-per-concrete type (TPC) は、"エンティティ分割" と共に EF6 でサポートされました。TPC は EF7 のロードマップに含まれています。
  • EF6 のストアド プロシージャ マッピングを使うと、作成、更新、削除の操作をストアド プロシージャに委任できます。 現在、EF Core では、読み取り用のストアド プロシージャへのマッピングのみが許可されています。 作成、更新、削除 (CUD) のサポートは、EF7 のロードマップ上にあります。
  • EF6 の複合型は、EF Core の所有型に似ています。 ただし、機能の完全なセットは、EF7 の値オブジェクトで対処されます。

ObjectContext を使わない

EF Core では、ObjectContext の代わりに DbContext が使われます。 IObjectContextAdapter が使われているコードを更新する必要があります。 これは、PreserveChanges または OverwriteChanges マージ オプションを使用するクエリで使われる場合がありました。 EF Core の同様の機能については、Reload メソッドを参照してください。

モデルの構成

EF6 と EF Core のモデルの設計方法には、多くの重要な違いがあります。 EF Core では、条件付きマッピングが完全にサポートされていません。 モデル ビルダーのバージョンがありません。

その他の違いには、次のようなものがあります。

型の検出

EF Core では、エンティティ型はエンジンによって次の 3 つの方法で検出されます。

  • DbContextDbSet<TEntity> を公開します。TEntity は追跡する型です。
  • コード内のどこかから Set<TEntity> を参照します。
  • 検出された型が参照している複合型は、再帰的に検出されます (たとえば、BlogPost を参照していて、Blog を検出できる場合は、Post も検出されます)

アセンブリは派生型に対してスキャン "されません"。

マッピング

EF6 の .Map() 拡張機能は、EF Core のオーバーロードと拡張メソッドに置き換えられています。 たとえば、'.HasDiscriminator()` を使って Table-Per-Hierarchy (TPH) を構成できます。 モデリングの継承に関する記事を参照してください。

継承マッピング

EF6 では、Table-Per-Hierarchy (TPH)、Table-Per-Type (TPT)、Table‐Per‐Concrete‐Class (TPC) がサポートされており、階層の各レベルでのさまざまなフレーバーのハイブリッド マッピングが有効でした。 EF Core では、モデル化された一方向 (TPT または TPH) への継承チェーンが引き続き必要であり、EF7 で TPC のサポートを追加する計画です。

モデリングの継承に関する記事を参照してください。

属性

EF6 では、プロパティのインデックス属性がサポートされていました。 EF Core では、これらは型レベルで適用されるため、複合インデックスを必要とするシナリオで簡単になるはずです。 EF Core では、データ注釈を含む複合キー (つまり、KeyAttribute と共に ColumnAttribute で Order を使用) はサポートされていません。

詳しくは、インデックスと制約に関する記事を参照してください。

必須と省略可能

EF Core モデル構築では、IsRequired はプリンシパル End で必要なもののみを構成します。 HasForeignKey がプリンシパル End を構成するようになりました。 コードを移植するには、代わりに .Navigation().IsRequired() を使う方が簡単です。 次に例を示します。

EF6:

modelBuilder.Entity<Instructor>()
    .HasRequired(t => t.OfficeAssignment)
    .WithRequiredPrincipal(t => t.Instructor);

EF Core 6:

modelBuilder.Entity<Instructor>()
    .HasOne(t => t.OfficeAssignment)
    .WithOne(t => t.Instructor)
    .HasForeignKey<OfficeAssignment>();

modelBuilder.Entity<Instructor>()
    .Navigation(t => t.OfficeAssignment)
    .IsRequired();

modelBuilder.Entity<OfficeAssignment>()
    .Navigation(t => t.Instructor)
    .IsRequired();

既定では、すべてが省略可能であるため、通常、.IsRequired(false) を呼び出す必要はありません。

空間サポート

EF Core は、空間サポートを提供するために、サードパーティ ライブラリのコミュニティ ライブラリ NetTopologySuite と統合されます。

独立した関連付け

EF Core では、独立した関連付け (2 つのエンティティ間のリレーションシップをエンティティ自体から独立して定義できるようにする EDM の概念) はサポートされていません。 EF Core でサポートされている同様の概念は、シャドウ プロパティです。

移行

EF Core では、データベース初期化子または自動移行はサポートされていません。 EF Core には migrate.exe はありませんが、移行バンドルを作成できます。

Visual Studio ツール

EF Core にはデザイナーがなく、データベースからモデルを更新する機能も、モデル優先フローもありません。 リバース エンジニアリング ウィザードも組み込みのテンプレートもありません。

これらの機能は EF Core には付属していませんが、追加のツールを提供する OSS コミュニティ プロジェクトがあります。 具体的には、EF Core Power Tools によって以下が提供されています。

  • データベース プロジェクト (.dacpac) をサポートする Visual Studio 内からのリバース エンジニアリング。 テンプレート ベースのコードのカスタマイズが含まれています。
  • モデルのグラフ化とスクリプトを使った DbContext の視覚的検査。
  • GUI を使った Visual Studio 内からの移行の管理。

コミュニティ ツールと拡張機能の完全な一覧については、「EF Core のツールと拡張機能」を参照してください。

変更追跡

EF6 と EF Core の変更追跡の処理方法には、いくつかの違いがあります。 次の表に、これらの概要を示します。

機能 EF6 EF Core
エンティティ状態 グラフ全体を追加またはアタッチする デタッチされたエンティティへのナビゲーションをサポートする
孤立 保持 削除済み
切断された自己追跡エンティティ サポートされています サポートなし
ミューテーション プロパティに対して実行 バッキング フィールドに対して実行*
データ バインディング .Local .Local プラス .ToObservableCollection または .ToBindingList
変更検出 グラフ全体 エンティティごと

* 既定では、プロパティ通知は EF Core ではトリガーされないため、通知エンティティを構成することが重要です。

EF Core では、EF6 ほど頻繁に変更検出が自動的に呼び出されないことに注意してください。

EF Core では、変更トラッカーの詳細な DebugView が導入されています。 詳しくは、「変更トラッカーによるデバッグ」を参照してください。

クエリ

EF6 には、EF Core には存在しないクエリ機能がいくつかあります。 これには以下が含まれます。

  • いくつかの一般的な C# 関数と SQL 関数のマッピング。
  • クエリと更新のコマンド ツリーのインターセプト。
  • テーブル値パラメーター (TVP) のサポート。

EF6 には、遅延読み込みプロキシのサポートが組み込まれています。 これは EF Core のオプトイン パッケージです (「関連データの遅延読み込み」を参照)。

EF Core を使うと、FromSQL を使って生 SQL の上に作成できます。