EF 基礎(第六章: 實體 Entity)

在 Entity Framework 中什麼是實體 Entity

在 EF 中一個實體就是程序域中的一個類,它在繼承的上下文類中包含在 DbSet<TEntity>中作爲類型屬性。EF API 把每一個實體映射到一張表,把實體的每一個屬性映射到數據庫中的列。

例如,在 school 程序中下面的StudentStudentAddressGrade是域類。

public class Student
{
    public int StudentID { get; set; }
    public string StudentName { get; set; }
    public DateTime? DateOfBirth { get; set; }
    public byte[]  Photo { get; set; }
    public decimal Height { get; set; }
    public float Weight { get; set; }

    public StudentAddress StudentAddress { get; set; }
    public Grade Grade { get; set; }
}

public partial class StudentAddress
{
    public int StudentID { get; set; }
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }

    public Student Student { get; set; }
}

public class Grade
{
    public int GradeId { get; set; }
    public string GradeName { get; set; }
    public string Section { get; set; }

    public ICollection<Student> Students { get; set; }
}

上面的這些類當它們在上下文類(繼承自DbContext)中被包含在DbSet<TEntity>中作爲屬性時,它們就變成了實體,如下所示。

public class SchoolContext : DbContext
{
    public SchoolContext()
    {

    }

    public DbSet<Student> Students { get; set; }
    public DbSet<StudentAddress> StudentAddresses { get; set; }
    public DbSet<Grade> Grades { get; set; }
}

在上面的上下文類中,StudentsStudentAddresses, 和 Grades 屬性的類型 DbSet<TEntity> 被稱爲實體集。Student,,StudentAddress,,和Grade 是實體 (也叫實體類型)。

一個實體(Entity)可以包含兩種類型的屬性:標量屬性(Scalar Properties)和導航屬性(Navigation Properties)。

標量屬性(Scalar Properties):

基本類型的屬性稱爲標量屬性。一個標量屬性可以存儲實際的數據。一個標量屬性可以映射到數據庫表的一個列。

導航屬性(Navigation Properties):

導航屬性代表和另一個實體之間的關係。
有兩種類型的導航屬性:引用導航(Reference Navigation)和集合導航(Collection Navigation)

引用導航屬性(Reference Navigation Property):

如果一個實體中包含一個實體類型的屬性,這個屬性就叫引用導航屬性。它代表多箇中的一個。

集合導航屬性(Collection Navigation Property):

如果一個實體包含一個集合類型的屬性,這個屬性就叫集合導航屬性。它代表多箇中的多個。

下面的圖表解釋了實體的屬性:
這裏寫圖片描述

實體的類型

Entity Framework 中的實體類型:

在Entity Framework 中有兩種實體類型:簡單對象實體(POCO Entities)和動態代理實體(Dynamic Proxy Entities)。

簡單對象實體(Pain Old CLR Object):

一個簡單對象實體是一個類,它不依賴於特定框架的中基類。它和任何 .NET CLR 中的類一樣,這就是它被稱爲簡單對象實體的原因。

簡單對象實體在 EF 6 和 EF Core 中都被支持。

Entity Data Model 中生成的實體類型的查詢,插入,更新和刪除中的大多數行爲,在簡單對象實體(也叫持久無關對象)中是一模一樣的。下面是一個 Student 簡單對象實體的一個例子。

public class Student
{
    public int StudentID { get; set; }
    public string StudentName { get; set; }
    public DateTime? DateOfBirth { get; set; }
    public byte[]  Photo { get; set; }
    public decimal Height { get; set; }
    public float Weight { get; set; }

    public StudentAddress StudentAddress { get; set; }
    public Grade Grade { get; set; }
}
動態代理實體(Dynamic Proxy Entities):

動態代理是一個封裝了簡單對象實體的運行時代理類。動態代理實體允許延遲加載(lazy loading)。

注意:只在 EF 6 中支持,在 EF Core 2.0 中暫時不支持。

一個簡單對象實體必須滿足一下條件才能成爲一個簡單對象代理:

  1. 一個簡單對象類必須聲明成 public 訪問。
  2. 一個簡單對象類必須不能是 sealed (在 Visual Basic 是 NotInheritable )。
  3. 一個簡單對象類必須不能是 abstract (在 Visual Basic 是 MustInherit )。
  4. 每一個導航屬性必須聲明成 public,virtual。
  5. 每一個集合屬性必須是 ICollection<T>
  6. 在上下文類中 ProxyCreationEnabled 選項不能是 false (默認是 true)。

下面的簡單對象實體滿足了上面的所有要求,在運行時可以變成一個動態代理實體。

public class Student
{
    public int StudentID { get; set; }
    public string StudentName { get; set; }
    public DateTime? DateOfBirth { get; set; }
    public byte[]  Photo { get; set; }
    public decimal Height { get; set; }
    public float Weight { get; set; }

    public virtual StudentAddress StudentAddress { get; set; }
    public virtual Grade Grade { get; set; }
}

注意:默認情況下,每一個實體的動態代理是打開的。然而,你可以在上下文類中通過設置context.Configuration.ProxyCreationEnabled = false;來關閉動態代理。
在運行時, EF API 將會爲上面的 Student實體創建一個動態代理的實例。Student的動態代理類型將會是System.Data.Entity.DynamicProxies.Student,如下所示:
這裏寫圖片描述
使用`ObjectContext.GetObjectType()可以找到被動態代理封裝在底層的類型,如下所示:
這裏寫圖片描述

實體狀態

Entity States in Entity Framework:

EF API 維持每一個實體聲明週期期間的狀態。通過上下文對每一個實體執行操作時都會有一個狀態。在 EF 6 中,實體的狀態用枚舉類型System.Data.Entity.EntityState表示,在 EF Core 中用枚舉類型Microsoft.EntityFrameworkCore.EntityState表示。這些枚舉類型有如下值:

  1. Added
  2. Modified
  3. Deleted
  4. Unchanged
  5. Detached

一旦上下文從數據庫中檢索數據,它就會保持所有實體對象的引用,也會保持對實體狀態的跟蹤維護隊實體屬性所作的修改。這個特性就叫做改變跟蹤(Change Tracking)。

實體狀態從 Unchanged 轉變成 Modified 狀態是唯一個由上下文自動完成情形。所有其它的改變必須顯式地使用合適的DbContext 或者 DbSet中的方法。

EF API 在 context.SaveChanges()被調用時會根據實體狀態創建並執行 INSERT,UPDATE,和 DELETE 命令。它對 Added 狀態的實體執行 INSERT 命令,對 Modified 狀態的實體執行 UPDATE 命令,對 Deleted 狀態的實體執行 DELETE 命令。上下文跟蹤 Detached 狀態的實體。下面圖表解釋了狀態實體的重要性:
這裏寫圖片描述

因此,實體狀態在 Entity Framework 中扮演了一個很重要的角色。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章