《Entity Framework 6 Recipes》中文翻譯系列 (40) ------ 第七章 使用對象服務之從跟蹤器中獲取實體與從命令行生成模型(想解決EF第一次查詢慢的,請閱讀)

翻譯的初衷以及爲何選擇《Entity Framework 6 Recipes》來學習,請看本系列開篇 

7-5  從跟蹤器中獲取實體

問題html

  你想建立一個擴展方法,從跟蹤器中獲取實體,用於數據保存前執行一些操做。數據庫

解決方案框架

  假設你有如圖7-7所示的模型。ide

圖7-7. 包含實體Technician和ServiceCall的模型工具

 

   在這個模型中,每一個技術員(technician)都有一些業務服務請求(service call),業務服務請求包含聯繫人姓名,問題。使用代碼清單7-4,建立一個擴展方法獲取實體狀態爲Added、Modifed或者Unchanged的全部實體。性能

代碼清單7-4. 建立一個擴展方法獲取實體狀態爲Added、Modifed或者Unchanged的全部實體 學習

 1  public static class Recipe5Program
 2     {
 3         public static void Run()
 4         {
 5             using (var context = new Recipe5Context())
 6             {
 7                 var tech1 = new Technician { Name = "Julie Kerns" };
 8                 var tech2 = new Technician { Name = "Robert Allison" };
 9                 context.ServiceCalls.Add(new ServiceCall
10                 {
11                     ContactName = "Robin Rosen",
12                     Issue = "Can't get satellite signal.",
13                     Technician = tech1
14                 });
15                 context.ServiceCalls.Add(new ServiceCall
16                 {
17                     ContactName = "Phillip Marlowe",
18                     Issue = "Channel not available",
19                     Technician = tech2
20                 });
21 
22                 //獲取Added狀態的實體
23                 foreach (var tech in
24                          context.ChangeTracker.GetEntities<Technician>())
25                 {
26                     Console.WriteLine("Technician: {0}", tech.Name);
27                     foreach (var call in tech.ServiceCalls)
28                     {
29                         Console.WriteLine("\tService Call: Contact {0} about {1}",
30                                            call.ContactName, call.Issue);
31                     }
32                 }
33             }
34             
35         }
36     }
37  public static class ChangeTrackerExtensions
38     {
39         public static IEnumerable<T> GetEntities<T>(this DbChangeTracker tracker)
40         {
41             var entities = tracker
42                      .Entries()
43                      .Where(entry => entry.State != EntityState.Detached && entry.Entity != null)
44                      .Select(entry => entry.Entity).OfType<T>();
45             return entities;
46         }
47     }

代碼清單7-4的輸出以下:測試

Technician: Julie Kerns
Service Call: Contact Robin Rosen about Can't get satellite signal.
Technician: Robert Allison
Service Call: Contact Phillip Marlowe about Channel not available

原理this

  在代碼清單7-4中,咱們實現了擴展方法GetEntities<T>(),它獲取上下中狀態爲Added,Modified,和Unchanged的全部實體。這是一個經常使用的方法,所以有理由只實現一次。在實現GetEntities<T>方法中,咱們使用LINQ-to Entities過濾Entries<T>()方法的整個集合。這個方法返回全部的非Detached狀態的條目。咱們從返回結果集中過濾掉關係以及爲null的條目,從剩下的條目中,咱們只選擇給定類型的條目。spa

  在許多重要場景中,你須要實現相似GetEntities<T>()方法的方法。好比,在SaveChanges事件中,你想驗證插入、修改或者刪除的實體。

 

 

 

 

 

7-6  從命令行生成模型

問題

  你想從命令行生成模型。

解決方案

  使用edmgen.exe程序,從命令行爲一個給定的數據庫生成模型。點擊開始菜單中Microsoft Visual Studio2012下面的Visual Studio 2012 Command Prompt(命令提示),訪問Visual Studio 2012命令提示工具。

  微軟的官方文檔爲edmgen命令提供了完整的命令行選項說明。 edmgen命令提供了許多有用的命令行選項。例如,下面的命令,會從測試數據庫中的全部表生成一個模型。

edmgen /mode:FullGeneration /project:Test /provider:"System.Data.SqlClient" 
/c:"server=localhost;integrated security=true;database=Test;"

  其它/model選項也是可使用的。其中有一個在持續構建過程當中頗有用,它是/mode: ValidateArtifacts。使用該選項,能夠生成一個或多個驗證過的層。你可能會使用下面的選項中的一個或是所有/inssdl 或者/incsdl。若是你想驗證映射層,那麼模型中三層都必須指定。

  在爲指定模型層生成文件時,你可使用/out選項給文件命名。假如,使用 /outcsdl:MyProject.csdl,將建立一個包含概念層定義的文件,文件名爲MyProject.csdl。其它層的用法與此類似。

原理

  edmgen命令提供了一種便捷的方式來自動構建模型,同時,它在預生成查詢視圖,爲每一個模型層生成獨立文件方面,是一個頗有用的工具。使用edmgen的一個限制是,它不能生成一個基於數據庫表的一個子集合的模型。

  使用edmgen命令預生成視圖,對一個應用的性能有極大的幫助。當一個查詢被執行時,實體框架必須構建一系列的視圖,這些視圖用於訪問和查詢數據庫。不使用edmgen實用工具,視圖的生成會在第一次實體框架調用時。 若是數據模型很小的話,第一次的初始化,不會帶來多大的風險。可是,若是數據模型很是大,或者很是複雜時,這樣的性能影響是不能接受的。在這種狀況下,咱們有足夠的理由來使用edmgen命令行實體工具


 

 

 

實體框架交流QQ羣:  458326058,歡迎有興趣的朋友加入一塊兒交流

謝謝你們的持續關注,個人博客地址:http://www.cnblogs.com/VolcanoCloud/

相關文章
相關標籤/搜索