實體框架 - 型別



在實體框架中,有兩種型別的實體允許開發人員將他們自己的自定義資料類與資料模型一起使用,而無需對資料類本身進行任何修改。

  • POCO 實體
  • 動態代理

POCO 實體

  • POCO 代表“普通舊”CLR 物件,可以用作現有域物件與您的資料模型。

  • 對映到實體的 POCO 資料類在資料模型中定義。

  • 它還支援與實體資料模型工具生成的實體型別相同的查詢、插入、更新和刪除行為。

  • 您可以使用 POCO 模板從概念模型生成與永續性無關的實體型別。

讓我們看一下以下概念實體資料模型示例。

Conceptual Entity Model

為上述實體模型生成 POCO 實體 -

步驟 1 - 右鍵單擊設計器視窗。它將顯示以下對話方塊。

Designer Window

步驟 2 - 選擇“新增程式碼生成項...”

Code Generation

步驟 3 - 選擇 EF 6.x DbContext 生成器,寫入名稱,然後單擊“新增”按鈕。

您將在解決方案資源管理器中看到已生成的 POCODemo.Context.tt 和 POCODemo.tt 模板。

Solution Explorer

POCODemo.Context 生成 DbContext 和您可以返回並用於查詢的物件集,例如上下文、學生和課程等。

Generate

另一個模板處理所有型別 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; }

   }
}

從實體模型為 Course 和 Enrollment 表生成類似的類。

動態代理

在建立 POCO 實體型別的例項時,實體框架通常會建立動態生成的派生型別的例項,該例項充當實體的代理。也可以說它是一個執行時代理類,就像 POCO 實體的包裝器類一樣。

  • 您可以覆蓋實體的某些屬性以在訪問屬性時自動執行操作。

  • 此機制用於支援關係的延遲載入和自動更改跟蹤。

  • 此技術也適用於使用程式碼優先和 EF 設計器建立的那些模型。

如果您希望實體框架支援相關物件的延遲載入並跟蹤 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。

廣告