重新認識了下Entity Framework

風靈使發表於2018-06-12

什麼是Entity Framework

Entity Framework是一個物件關係對映O/RM框架。

Entity Framework讓開發者可以像操作領域物件(domain-specific objects)那樣操作關係型資料(relational data)。

Entity Framework減少了大部分通常需要編寫的資料操作程式碼。

Entity Framework中可以使用LINQ來查詢資料,使用強型別(strongly typed objects)來檢索和運算元據。

Entity Framework提供了以下服務,使開發者可以更加側重於程式業務邏輯,而非資料訪問的基本操作。

  1. 狀態或變更跟蹤(change tracking)
  2. 身份或主鍵識別(identity resolution)
  3. 懶載入(lazy loading)
  4. 查詢翻譯(query translation)

Entity FrameworkADO.NET的加強,它給開發者提供了資料庫訪問和儲存的自動化機制。

Entity Framework是一個開源框架。

什麼是O/RM

O/RM是一種工具,可以自動地把領域物件資料儲存到關係型資料庫(如MS SQL Server),而不需要大量的編碼。

O/RM包含三個重要的部分:

  1. 領域物件(Domain class objects):我們定義的類。

  2. 關係型資料庫物件(Relational database objects):資料庫表,檢視,儲存過程等。

  3. 對映資訊(Mapping information):領域物件與關係型資料庫物件之間轉換的資訊。

O/RM允許開發者把資料庫設計和領域物件設計獨立開,讓程式更具有可維護性和可擴充套件性。

它還提供了基本的增刪改查的功能,開發者不需要手動再編寫這部分程式碼。

一個典型的資料庫與應用程式的O/RM互動如下圖所示:
這裡寫圖片描述

Entity Framework的結構

Entity Framework的總體結構如下圖所示。
這裡寫圖片描述

EDM(Entity Data Model):EDM包含三個主要的部分 - 概念模型(Conceptual model)、儲存模型(Storage model)和對映(Mapping)。

  1. Conceptual model:概念模型包含了模型的類定義,以及類之間的關係。概念模型的設計獨立於資料庫表設計。

  2. Storage model:儲存模型是資料庫設計模型,包含了資料庫表,檢視,儲存過程,以及它們的之間的關係和鍵。

  3. Mapping:對映包含了概念模型對映到儲存模型的相關資訊。

LINQ to Entities:一種基於物件模型編寫的查詢語言,它將返回概念模型中設計的實體。

Entity SQL:另一種和LINQ to Entities相似的查詢語言,但是它們還是有一些差異的,開發者還是需要單獨花時間去學習它。

Object Service:資料庫資料訪問的主要入口,主要職責是物化(materialization),把Entity Client Data Provider返回的資料轉換成實體物件結構。

Entity Client Data Provider:把LINQ to EntitiesEntity SQL轉換成資料庫SQL。和ADO.Net Data Provider進行通訊,傳送或檢索資料庫資料。

ADO.Net Data Provider:ADO.Net Data Provider使用標準的ADO.Net和資料庫進行互動。

Entity Framework的開發模式

Entity Framework提供了三種開發模式:

  1. Code First

  2. Database First

  3. Model First

Code First
這裡寫圖片描述
Code First的開發模式中,要避免使用視覺模型設計器(EDMX),一般是先編寫POCO類,然後根據這些類去生成資料庫。

那些遵循領域驅動開發(DDD)原則的開發者,更傾向於一開始先編寫自己的領域類,然後再生成資料庫來實現資料持久化。

Database First:
這裡寫圖片描述
通過已有的資料庫來生成EDMX(Entity Data Model)的開發模式就是Database First的開發模式。

如果資料庫變更了,EDMX(Entity Data Model)也會更新。同時,Database First也支援儲存過程,檢視等。

Model First:
這裡寫圖片描述
Model FirstCode FirstDatabase First的一種折中開發模式,它提供視覺模型設計器(EDMX)來設計資料模型,然後根據資料庫模型來生成資料庫以及領域類。

總結:

  1. Code First是先編寫領域類,然後根據類來生成資料庫,無視覺模型設計器(EDMX)。

  2. Database First是根據資料庫生成視覺模型設計器(EDMX)及領域類。

  3. Model First是先生成視覺模型設計器(EDMX),然後根據EDMX生成資料庫及領域類。

選擇Entity Framework開發模式

這裡寫圖片描述
1. 如果你有一個現成的程式,並且已經定義了領域類,那麼,可以使用Code First的開發模式來生成資料庫進行開發。

  1. 如果你有已個現成的資料庫,那麼,可以使用Database First的開發模式來生成EDM進行開發。

  2. 如果你沒有現成的資料庫,也沒有定義好的領域類,而你更傾向於使用圖形化介面來設計資料庫模型,那麼,可以使用Model First的開發模式進行開發。

我個人的話,任何情景都會使用Code First的開發模式,因為它比較靈活,但是對開發者本身的要求會更高一些。

DbContext

這裡寫圖片描述
DbContextEntity Framework的一個重要部分,它是領域或實體類與資料庫之間的橋樑。

DbContext是一個很重要的類,主要職責是以物件的方式和資料進行互動,它包含以下活動:

EntitySetDbContext包含實體集合(DbSet<TEntity>),把實體對映到資料庫表。

QueryingDbContextLINQ to Entities查詢轉換成SQL查詢,併傳送到資料庫。

Change TrackingDbContext會跟蹤從資料庫查詢出來的實體的狀態變更。

Persisting DataDbContext根據實體的狀態提供插入,更新和刪除等資料庫操作。

CachingDbContext預設實現一級快取,在Context類的生命週期期間,它會儲存檢索出來的實體。

Manage RelationshipDatabase FirstModel First中,使用CSDL,MSL,SSDL來管理關係,在Code First中使用Fluent API來管理關係。

Object MaterializationDbContext把表原始資料轉換成實體物件。

實體生命週期

在實體的生命期中,每個實體都有一個基於上下文(DbContext)的操作的實體狀態。

實體狀態是一個System.Data.Entity.EntityState型別的列舉,它包含以下的值:

Added:實體正在被上下文跟蹤,但還不存在於資料庫中。

Deleted:實體正在被上下文跟蹤並存在於資料庫,但被標記為從資料庫刪除。

Modified:實體正在被上下文跟蹤並存在於資料庫,而且實體的一些或所有屬性的值被修改了。

Unchanged:實體正在被上下文跟蹤並存在於資料庫,但實體的所有屬性值都沒被修改。

Detached:實體不被上下文跟蹤。

下圖說明了實體狀態如何影響資料庫操作。
這裡寫圖片描述
1. 新的實體具有Added的狀態,DbContext後續會在資料庫中執行插入操作。

  1. 通過LINQ檢索出來的實體具有Unchanged的狀態,但如果呼叫了AsNoTracking()方法,其狀態為Detached

  2. 修改了檢索出來的實體的屬性值,實體會修改狀態為ModifiedDbContext後續會在資料庫中執行更新操作。

  3. 需要刪除的實體會具有Deleted的狀態,DbContext後續會在資料庫中執行刪除操作。

  4. 對於DbContext中已有的實體,可以通過dbContext.Entry(entity).State = EntityState.Detached的方式把狀態設定為Detached

Entity Framework版本

版本 引入功能
EF 3.5 Database First模式下基本的O/RM支援。
EF 4.0 POCO的支援, 懶載入, 可測試性提升,定製化程式碼生成,以及引入Model First開發模式。
EF 4.1 ObjectContext的基礎上簡化了DBContext API,引入Code First開發模式。
EF 4.3 引入Code First Migrations,可以根據定義的Code First模型來建立或修改資料庫。
EF 5.0 宣佈EF為開源專案。引入了列舉支援,表值函式, 空間資料型別,模型多圖表,設計介面著色形狀,批量匯入儲存過程,EF Power Tools,以及各種效能提升。
EF 6.0 引入了許多Code First & EF設計相關的新功能,如非同步操作(asynchronous),彈性連線(connection resiliency),依賴解析(dependency resolution)等。

注:Entity Framework Core不在本文討論範圍。

相關文章