Entity-framework-lazy-loading

提供:Dev Guides
移動先:案内検索

Entity Framework-遅延読み込み

遅延読み込みとは、エンティティを参照するプロパティに最初にアクセスしたときに、エンティティまたはエンティティのコレクションがデータベースから自動的に読み込まれるプロセスです。 遅延読み込みとは、特に要求するまで、関連データの読み込みを遅らせることです。

  • POCOエンティティタイプを使用する場合、派生プロキシタイプのインスタンスを作成し、仮想プロパティをオーバーライドしてロードフックを追加することにより、遅延ロードが実現されます。
  • 遅延読み込みはほとんどデフォルトです。
  • 既定の構成をそのままにして、遅延ロード以外の何かが必要であることをクエリでEntity Frameworkに明示的に指定しない場合、遅延ロードが得られます。
  • たとえば、Studentエンティティクラスを使用する場合、Enrollmentsナビゲーションプロパティに最初にアクセスすると、関連するEnrollmentsがロードされます。
  • ナビゲーションプロパティは、パブリック、仮想として定義する必要があります。 プロパティが仮想として定義されていない場合、コンテキストは遅延読み込みを実行しません。

以下は、Enrollmentsのナビゲーションプロパティを含むStudentクラスです。

public partial class Student {

   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; }

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

最初に学生リストがデータベースからロードされ、次に必要なときに特定の学生の登録がロードされる単純な例を見てみましょう。

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

        //Loading students only
         IList<Student> students = context.Students.ToList<Student>();

         foreach (var student in students) {

            string name = student.FirstMidName + " " + student.LastName;
            Console.WriteLine("ID: {0}, Name: {1}", student.ID, name);

            foreach (var enrollment in student.Enrollments) {
               Console.WriteLine("Enrollment ID: {0}, Course ID: {1}",
                  enrollment.EnrollmentID, enrollment.CourseID);
            }
         }

         Console.ReadKey();
      }
   }
}

上記のコードをコンパイルして実行すると、次の出力が表示されます。

ID: 1, Name: Ali Alexander
       Enrollment ID: 1, Course ID: 1050
       Enrollment ID: 2, Course ID: 4022
       Enrollment ID: 3, Course ID: 4041
ID: 2, Name: Meredith Alonso
       Enrollment ID: 4, Course ID: 1045
       Enrollment ID: 5, Course ID: 3141
       Enrollment ID: 6, Course ID: 2021
ID: 3, Name: Arturo Anand
       Enrollment ID: 7, Course ID: 1050
ID: 4, Name: Gytis Barzdukas
       Enrollment ID: 8, Course ID: 1050
       Enrollment ID: 9, Course ID: 4022
ID: 5, Name: Yan Li
       Enrollment ID: 10, Course ID: 4041
ID: 6, Name: Peggy Justice
       Enrollment ID: 11, Course ID: 1045
ID: 7, Name: Laura Norman
       Enrollment ID: 12, Course ID: 3141

遅延読み込みをオフにする

遅延読み込みとシリアル化はうまく混ざりません。注意しないと、遅延読み込みが有効になっているからといって、データベース全体をクエリすることになります。 エンティティをシリアル化する前に、遅延読み込みをオフにすることをお勧めします。

特定のナビゲーションプロパティをオフにする

次の例に示すように、Enrollmentsプロパティを非仮想にすることで、Enrollmentsコレクションの遅延読み込みをオフにできます。

public partial class Student {

   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; }

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

すべてのエンティティに対してオフにする

次の例に示すように、Configurationプロパティのフラグをfalseに設定することにより、コンテキスト内のすべてのエンティティの遅延読み込みをオフにできます。

public partial class UniContextEntities : DbContext {

   public UniContextEntities(): base("name = UniContextEntities") {
      this.Configuration.LazyLoadingEnabled = false;
   }

   protected override void OnModelCreating(DbModelBuilder modelBuilder) {
      throw new UnintentionalCodeFirstException();
   }
}

遅延読み込みをオフにした後、上記の例を再度実行すると、登録が読み込まれず、学生データのみが取得されることがわかります。

ID: 1, Name: Ali Alexander
ID: 2, Name: Meredith Alons
ID: 3, Name: Arturo Anand
ID: 4, Name: Gytis Barzduka
ID: 5, Name: Yan Li
ID: 6, Name: Peggy Justice
ID: 7, Name: Laura Norman
ID: 8, Name: Nino Olivetto

理解を深めるために、上記の例を段階的に実行することをお勧めします。