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


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

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

問題

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

解決方案

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

圖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

原理

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

  在許多重要場景中,你需要實現類似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/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM