問題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事件中,你想驗證插入、修改或者刪除的實體。
問題
你想從命令行生成模型。
解決方案
使用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/