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 Framework是ADO.NET的加強,它給開發者提供了數據庫訪問和存儲的自動化機制。
Entity Framework是一個開源框架。
O/RM是一種工具,可以自動地把領域對象數據存儲到關系型數據庫(如MS SQL Server),而不需要大量的編碼。
O/RM包含三個重要的部分:
1. 領域對象(Domain class objects):我們定義的類。
2. 關系型數據庫對象(Relational database objects):數據庫表,視圖,存儲過程等。
3. 映射信息(Mapping information):領域對象與關系型數據庫對象之間轉換的信息。
O/RM允許開發者把數據庫設計和領域對象設計獨立開,讓程序更具有可維護性和可擴展性。
它還提供了基本的增刪改查的功能,開發者不需要手動再編寫這部分代碼。
一個典型的數據庫與應用程序的O/RM交互如下圖所示:
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 Entities或Entity SQL轉換成數據庫SQL。和ADO.Net Data Provider進行通訊,發送或檢索數據庫數據。
ADO.Net Data Provider:ADO.Net Data Provider使用標准的ADO.Net和數據庫進行交互。
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 First是Code First和Database First的一種折中開發模式,它提供視覺模型設計器(EDMX)來設計數據模型,然後根據數據庫模型來生成數據庫以及領域類。
總結:
1. Code First是先編寫領域類,然後根據類來生成數據庫,無視覺模型設計器(EDMX)。
2. Database First是根據數據庫生成視覺模型設計器(EDMX)及領域類。
3. Model First是先生成視覺模型設計器(EDMX),然後根據EDMX生成數據庫及領域類。
1. 如果你有一個現成的程序,並且已經定義了領域類,那麼,可以使用Code First的開發模式來生成數據庫進行開發。
2. 如果你有已個現成的數據庫,那麼,可以使用Database First的開發模式來生成EDM進行開發。
3. 如果你沒有現成的數據庫,也沒有定義好的領域類,而你更傾向於使用圖形化界面來設計數據庫模型,那麼,可以使用Model First的開發模式進行開發。
我個人的話,任何情景都會使用Code First的開發模式,因為它比較靈活,但是對開發者本身的要求會更高一些。
DbContext是Entity Framework的一個重要部分,它是領域或實體類與數據庫之間的橋梁。
DbContext是一個很重要的類,主要職責是以對象的方式和數據進行交互,它包含以下活動:
EntitySet:DbContext包含實體集合(DbSet<TEntity>),把實體映射到數據庫表。
Querying:DbContext把LINQ to Entities查詢轉換成SQL查詢,並發送到數據庫。
Change Tracking:DbContext會跟蹤從數據庫查詢出來的實體的狀態變更。
Persisting Data:DbContext根據實體的狀態提供插入,更新和刪除等數據庫操作。
Caching:DbContext默認實現一級緩存,在Context類的生命周期期間,它會保存檢索出來的實體。
Manage Relationship:Database First或Model First中,使用CSDL,MSL,SSDL來管理關系,在Code First中使用Fluent API來管理關系。
Object Materialization:DbContext把表原始數據轉換成實體對象。
在實體的生命期中,每個實體都有一個基於上下文(DbContext)的操作的實體狀態。
實體狀態是一個System.Data.Entity.EntityState類型的枚舉,它包含以下的值:
Added:實體正在被上下文跟蹤,但還不存在於數據庫中。
Deleted:實體正在被上下文跟蹤並存在於數據庫,但被標記為從數據庫刪除。
Modified:實體正在被上下文跟蹤並存在於數據庫,而且實體的一些或所有屬性的值被修改了。
Unchanged:實體正在被上下文跟蹤並存在於數據庫,但實體的所有屬性值都沒被修改。
Detached:實體不被上下文跟蹤。
下圖說明了實體狀態如何影響數據庫操作。
1. 新的實體具有Added的狀態,DbContext後續會在數據庫中執行插入操作。
2. 通過LINQ檢索出來的實體具有Unchanged的狀態,但如果調用了AsNoTracking()方法,其狀態為Detached。
3. 修改了檢索出來的實體的屬性值,實體會修改狀態為Modified,DbContext後續會在數據庫中執行更新操作。
4. 需要刪除的實體會具有Deleted的狀態,DbContext後續會在數據庫中執行刪除操作。
5. 對於DbContext中已有的實體,可以通過dbContext.Entry(entity).State = EntityState.Detached的方式把狀態設置為Detached。
版本
引入功能
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不在本文討論范圍。
本文大部分內容來自:Entity Framework Tutorial
少量內容參考:Entity Framework官網