標籤:des style blog io color ar 使用 sp strong
寫這篇部落格的時候,聽聞EF7都發布半年了,吐糟下巨硬,同時對自己老處在追趕者的角色深感不滿。
言歸正傳,提起DbContext就不得不提ObjectContext,在EF第一個版本發布以來,其中最重要的組件就是ObjectContext,ObjectContext提供了概念上的模型來讓我們與資料庫互動(寫查詢運算式、執行查詢,跟蹤模型修改狀態,持久化修改到資料庫),他同時也與其他重要的EF類來進行互動操作:
- ObjectSet:在記憶體中對實體進行集合操作。
- ObjectQuery:針對概念性模型的類型化查詢。
所有這些類充滿了特性和功能--有的很複雜,大多數只在特殊情況下是必須的。在經曆了Entity Framework的兩個版本之後(.NET 3.5 SP1 .NET 4)逐漸明確了,開發人員大部分只會用到這些功能的一部分,但不幸的是,對於我們經常做的大部分的任務編碼以及查詢都有點困難。
意識到這一點之後,EF團隊開始對開發人員有愛了,他們的解決方案是建立了一些新類封裝了ObjectContext功能的子集,開發人員在一般情況下就無需與ObjectContext打交道了(除了一些進階主題),這些新類是隨同EF4.1一起發布,是EF4.1的一部分。
這些新類就是指:DbContext,DbSet,DbQuery。同時他們是DbContext API 的一部分。這個新的API 不僅僅包含DbContext,而且包含了EF團隊為其開發的一些新的功能。DbContext API 是包含在Entity Framework.dll中的,這個類庫同時也包含了驅動Code First開發的邏輯,這個類庫與.NET是分開的,被發布在EntityFramework NuGet package。Entity Framework的主要部分是.NET Framework一部分(主要是System.Data.Entity.dll)。被包含在.NET Framework裡面的這些組件被認為是Entity Framework“核心組件”,而DbContext API是完全獨立的,與這些“核心組件”是分開的。Entity Framework團隊意識到整合在.NET Framework裡面不是一個好的選擇,他們正致力於把更多的“核心組件”從.NET Framework中移到到Entity Framework.dll中,這樣發布新的Entity Framework的新功能都無需等到.NET Framework新版本發布。
下表是DbContext API 的功能概覽
|
DbContext
API 類/功能 |
相關的EF4
類/功能 |
目的 |
DbContext API 優點 |
| DbContext |
ObjectContext |
代表與資料庫連接的會話,提供了查詢、狀態跟蹤、儲存等功能 |
簡化了大部分ObjectContext功能 |
| DbSet |
ObjectSet |
對實體類型提供了集合操作,比如Add、Attach、Remove。
繼承了DbQuery,所以可以提供查詢功能 |
簡化了大部分ObjectSet功能 |
| DbQuery |
ObjectQuery |
提供查詢功能 |
DbQuery的查詢功能整合在DbSet中,
所以不用直接操作DbQuery |
|
Change
Tracker API |
ObjectContext.
ObjectStateManager |
獲得實體變化跟蹤資訊以及相關的操作(original values、current values)
受上下文管理 |
更簡單、更直觀的API |
| Validation API |
N/A |
提供自動的資料驗證。這個API 利用了.NET 4原生的驗證功能 |
新的 |
| Code First Model Building |
N/A |
基於已有的類以及配置資訊來建立資料庫及其中繼資料 |
新的 |
如何在自己項目中使用DbContext API
通過巨硬的NuGet 以及Library Package Manager 上下載Entity Framework組件,然後一切交給宇宙第一神IDE吧。
DbContext API的一些亮點
讓我們看看DbContext API 是如何來減少工作量的,如何減少當然要以ObjectContext來對比。
樣本中包含Person Destination Trip三個實體
Example 1-1 ObjectContext寫法
1 public class BreakAwayContext : ObjectContext 2 { 3 private ObjectSet<Person> _ people; 4 private ObjectSet<Destination> _destinations; 5 private ObjectSet<Trip> _trips; 6 public ObjectSet<Person> People 7 { 8 get { return _people ?? (_people = CreateObjectSet<Person>("People")); } 9 }10 public ObjectSet< Destination > Contacts11 {12 get { return _ destinations?? (_destinations =13 CreateObjectSet< Destination >("Destinations")); }14 }15 public ObjectSet<Trip> Trips16 {17 get { return _ trips?? (_trips = CreateObjectSet<Trip>("Trips")); }18 }19 }
Example 1-2 DbContext 寫法
1 public class BreakAwayContext : DbContext2 {3 public DbSet<Person> People { get; set; }4 public DbSet<Destination> Destinations { get; set; }5 public DbSet<Trip> Trips { get; set; }6 }
簡化以及最佳化一目瞭然。
減少以及簡化了集合操作
在Entity Framework 4中,添加執行個體到實體集中,你可以使用ObjectContext.AddObject或者ObjectSet.AddObject.當添加執行個體到ObjectContext中的時候,ObjectContext需要知道這個執行個體屬於哪個實 體集合,所以對於ObjectSet.AddObject你必須以文本的形式指明實體集名稱,比如:
context.AddObject("Trips",newTrip);
使用ObjectSet.AddObject的話稍微簡化點:context.Trips.AddObject(newTrip);至於ObjectContext.AddObject繼續存在於EF4的原因在於與早期版本的向後相容性,但開發人員並不會意識到這個原因, 只會被這兩種寫法搞迷糊了。
因為DbContext API是新的,我們無需擔心與早期版本的向後相容性,所以DbContext並沒有提供在context上面添加執行個體的方法,只是在DbSet上面添加了Add方法:
context.Trips.Add(newTrip);
ObjectContext還提供了AttachObject和DeleteObject方法,同樣的DbContext並沒有提供類似的方法,這些方法全部在DbSet上面提供:Attach、Remove。
使用ID與DbSet.Find檢索一個實體
開發人員經常要做的一件事就是根據key來查詢相應的實體,EF4時代我們都是寫如下的查詢語句:
context.People.SingleOrDefault(p=>p.Id=Id);
現在DbSet提供了Find方法:
context.People.Find(Id);
使用Find有個優點,調用SingleOrDefault方法會一直查詢資料庫,而使用Find方法,會首先查詢記憶體中是否存在相關執行個體,如果有,直接返回,如果沒有才會去查詢資料庫,對效能提高是大大的。
-------To Be Continue.
DbContext API 介紹