エンティティフレームワーク-タイプ

Entity Frameworkには、開発者がデータクラス自体に変更を加えることなく、データモデルと一緒に独自のカスタムデータクラスを使用できるようにする2種類のエンティティがあります。

  • POCOエンティティ
  • 動的プロキシ

POCOエンティティ

  • POCOは、データモデルで既存のドメインオブジェクトとして使用できる「プレーンオールド」CLRオブジェクトの略です。

  • エンティティにマップされるPOCOデータクラスは、データモデルで定義されます。

  • また、エンティティデータモデルツールによって生成されるエンティティタイプと同じクエリ、挿入、更新、および削除の動作のほとんどをサポートします。

  • POCOテンプレートを使用して、概念モデルから永続性を無視するエンティティタイプを生成できます。

次の概念エンティティデータモデルの例を見てみましょう。

上記のエンティティモデルのPOCOエンティティを生成するには-

Step 1−デザイナウィンドウを右クリックします。次のダイアログが表示されます。

Step 2 − [コード生成アイテムの追加...]を選択します。

Step 3 − EF 6.x DbContext Generatorを選択し、名前を書き込んでから、[追加]ボタンをクリックします。

ソリューションエクスプローラーで、POCODemo.Context.ttおよびPOCODemo.ttテンプレートが生成されていることがわかります。

POCODemo.Contextは、DbContextとオブジェクトセットを生成します。これらを返し、クエリに使用できます。たとえば、コンテキスト、学生、コースなどです。

もう1つのテンプレートは、Student、Coursesなどのすべてのタイプを処理します。以下は、エンティティモデルから自動的に生成されるStudentクラスのコードです。

namespace ConsoleApplication1 {

   using System;
   using System.Collections.Generic;

   public partial class Student {

      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", 
         "CA2214:DoNotCallOverridableMethodsInConstructors")]

      public Student() {
         this.Enrollments = new HashSet<Enrollment>();
      }

      public int ID { get; set; }
      public string LastName { get; set; }
      public string FirstMidName { get; set; }
      public System.DateTime EnrollmentDate { get; set; }

      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", 
         CA2227:CollectionPropertiesShouldBeReadOnly")]

      public virtual ICollection<Enrollment> Enrollments { get; set; }

   }
}

同様のクラスが、エンティティモデルのコーステーブルと登録テーブルに対して生成されます。

動的プロキシ

POCOエンティティタイプのインスタンスを作成する場合、Entity Frameworkは、エンティティのプロキシとして機能する動的に生成された派生タイプのインスタンスを作成することがよくあります。また、POCOエンティティのラッパークラスのようなランタイムプロキシクラスであるとも言えます。

  • プロパティにアクセスしたときにアクションを自動的に実行するために、エンティティの一部のプロパティをオーバーライドできます。

  • このメカニズムは、関係の遅延読み込みと自動変更追跡をサポートするために使用されます。

  • この手法は、CodeFirstとEFDesignerで作成されたモデルにも適用されます。

Entity Frameworkで関連オブジェクトの遅延読み込みをサポートし、POCOクラスの変更を追跡する場合、POCOクラスは次の要件を満たす必要があります-

  • カスタムデータクラスは、パブリックアクセスで宣言する必要があります。

  • カスタムデータクラスは封印してはなりません。

  • カスタムデータクラスは抽象であってはなりません。

  • カスタムデータクラスには、パラメーターを持たないパブリックコンストラクターまたは保護されたコンストラクターが必要です。

  • CreateObjectメソッドを使用してPOCOエンティティのプロキシを作成する場合は、パラメーターなしで保護されたコンストラクターを使用します。

  • CreateObjectメソッドを呼び出しても、プロキシの作成が保証されるわけではありません。POCOクラスは、このトピックで説明されている他の要件に従う必要があります。

  • プロキシクラスがこれらのインターフェイスを実装しているため、クラスはIEntityWithChangeTrackerまたはIEntityWithRelationshipsインターフェイスを実装できません。

  • ProxyCreationEnabledオプションをtrueに設定する必要があります。

次の例は、動的プロキシエンティティクラスです。

public partial class Course {

   public Course() {
      this.Enrollments = new HashSet<Enrollment>();
   }

   public int CourseID { get; set; }
   public string Title { get; set; }
   public int Credits { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

プロキシオブジェクトの作成を無効にするには、ProxyCreationEnabledプロパティの値をfalseに設定します。