Entity Framework7 有哪些不同?之具體功能
前面我們介紹了關於EF7的新特性、開發計划和入門介紹。今天,我們來看看EF7的具體新功能及用法。本文中的環境,為EF7入門里介紹的環境。
1、在Linq to Entity 查詢中對列使用類型轉換,請見如下代碼:
1 var result = db.Blogs.Where((b => Convert.ToInt32(b.IntString) == 2)).FirstOrDefault();
代碼中的Convert.ToInt32(b.IntString),對列IntString轉換成Int32類型。生成SQL語句如下:
1 SELECT TOP(1) [b].[BlogId], [b].[IntString], [b].[Url] 2 FROM [Blog] AS [b] 3 WHERE (CONVERT(int, [b].[IntString]) = 2)
備注,可能不少朋友想在Linq To Entity中使用 Tostring()方法,這在EF6.1中就支持了,平常還聽到不少朋友在感嘆,要是EF7支持枚舉就好了,其實,這個功能也是在EF6.1中就支持了。
2、Code-First下用數據遷移更新數據庫時使用修改(Alter)代替刪除(Dropping)后重新創建
在這之前,相信不少人吃過虧,因為之前模型發生變更,使用數據遷移更新數據庫結構時,是先刪除數據庫,再重新創建,這樣的問題是,會造成數據丟失。聽說有人因為不熟悉這功能,把生產環境的數據也給弄丟失了。
3、刪除孤兒(orphans)記錄
這個,讓我們直接舉例來說明。假設我們有一個對多關系的模型,Blog和Post,在Blog實體中有導航屬性Posts。在數據庫中Post通過外鍵BlogId與Blog關聯,且BlogId不能為空。如果我們在Blog實體中,使用如下方法 Posts.Remove(post); 然后調用上下文對象中的SaveChages()保存修改。按理是應該把post對象的記錄給刪除掉,但實際的情況是,我得到了一個異常。原因是現在EF版本是這樣處理的:它把從Blogs導航屬性集體中移除的post對象的BlogId設置為null,然而數據庫中對應的外鍵又不能為null,於是保存失敗。這個post也被形象的叫做孤兒(與父對象脫離了關系)對象。 EF7將會解決這一問題。代碼如下:
1 var result = db.Blogs.Where((b => Convert.ToInt32(b.IntString) == 2)).FirstOrDefault(); 2 3 if (result != null) 4 { 5 var post = db.Posts.FirstOrDefault(p => p.PostId == 1); 6 result.Posts.Remove(post); 7 db.SaveChanges(); 8 }
下圖是EF6下的異常
很遺憾的是,現在EF7的最新預發行版本EF7.0.0-beta7還沒有解決這個問題,但異常的內容發生了改變.
相信在后面版本會得到處理,因為EF團隊已經承諾要解決這個問題。
4、日志記錄
在日志中查看EF生成的SQL,相信這種方法幫助過不少的人(當然不是全部,因為有人還不知道有這東西,做開發就得不停的學習!)。EF6中,大家是使用類似如下的代碼來記錄SQL語句:
1 db.Database.Log = s => Console.WriteLine(s);
EF7中,為了使用Microsoft.Framework.Logging日志框架和依賴注入,關於日志的接口是幾經變化。首先是去掉了上面的的Database.Log,在EF7.0.0-beta2中使用如下的方式:
1 db.Configuration.LoggerFactory.AddProvider(new DiagnosticsLoggerProvider( 2 new SourceSwitch("SourceSwitch", "Verbose"), 3 new ConsoleTraceListener()));
后來,微軟就去掉了db.Configuration,使用如下的方式:
1 IServiceProvider contextServices = ((IDbContextServices)db).ScopedServiceProvider; 2 var loggerFactory = contextServices.GetRequiredService<ILoggerFactory>(); 3 oggerFactory.AddConsole(LogLevel.Verbose);
現在的版本中,又變成如下方式:
1 var service = ((IAccessor<IServiceProvider>)db).Service; 2 var loggerFactory = service.GetRequiredService<ILoggerFactory>(); 3 loggerFactory.AddConsole(LogLevel.Verbose);
也許,后面的Beta8,RC版本還會有調整,但可以確認的是,它會越來越強。從日志接口的變化也可以看,EF7目錄處於開發過程中,變化會很大。因此,文中介紹的功能,都是以目前已有的版本為基礎,后面可能會變生變化,這一點要請大家注意。
今天就先到這里,有點不舒服。改天再慢慢寫。謝謝你的理解。
實體框架交流QQ群: 458326058,歡迎有興趣的朋友加入一起交流
謝謝大家的持續關注,我的博客地址:http://www.cnblogs.com/VolcanoCloud/