EF6學習筆記三十:性能優化——預編譯視圖
要專業系統地學習EF推薦《你必須掌握的Entity Framework 6.x與Core 2.0》。這本書作者(汪鵬,Jeffcky)的博客:https://www.cnblogs.com/CreateMyself/
來到性能優化這裏了。這裏首先引用作者的一句話:EF的性能問題一直是.NET程序員熱聊的話題,實際情況不是性能差,而是需要我們掌握如何規避陷阱以及影響性能的坑。
本次的學習疑點有很多
通常情況下,當首次使用EF時,查詢數據的過程非常漫長,因為它必須生成用於計算要運行的查詢視圖。
解決方法有兩種,第一,采用第三方庫;第二,使用EF提供的API
既然有提供API那我就沒去弄第三方庫了,更多的解決方案請參考書上的內容。
在EF6.2.x中可以為EF加上配置,EF6.1.X中則不一樣
public class EFConfiguration: DbConfiguration { public EFConfiguration() { SetModelStore(new DefaultDbModelStore(Directory.GetCurrentDirectory())); } }
當首次調用Enable-migrations命令後,會在VS編譯器所在目錄生成模型edmx緩存,在項目中的bin/bebug裏面也會生成一個這個的文件
當你執行enable-migrations遇到下面這樣的情況後請以管理員的身份運行VS在enable-migrations
vs安裝目錄
項目文件目錄
這裏就不得不去看一下edmx是什麽東西。因為即使這樣做了之後我也不知道優化在哪裏?難道edmx就是預編譯視圖?不是,作者並沒有這麽說
edmx是EF的核心文件,在我們使用Dbfirst模式的時候就會生成edmx文件,一個XML文件,裏面的內容來看一下
復習一下EF的架構
Conceptual Schema Define Layer (CSDL) 概念架構定義層 對象的世界(開發人員面向這一層)
Mapping Schema Layer (MSL) 映射架構層 映射
Storage Schema Define Layer (SSDL) 存儲架構定義層 數據的世界(這一層專門和數據庫打交道)
那麽edmx就是對這幾層具體的配置,不知道具體的情況我就不過多的瞎說了
來一個笨的辦法,將裏面的單詞都翻譯一樣,讀個似懂非懂也好
ConceptualModels 概念模型
Mappings 映射
StorageModels 存儲模型
看了一下,雖說edmx是個XML文件,但是他其實可以可視化讀取的 ,就像圖片可以用圖片查看器打開一樣
我們把剛剛生成的edmx文件復制到項目中來看看,它對應的就是這個!是不是很熟悉
在我剛剛開始接觸EF的時候我用到以前根本就不知道的Dbfirst這些概念也弄出過這個,可視化的去進行建模
可以看到還有一個Model.tt的文件,這個關於到T4模塊,對這一塊我比較空白,大家可以參考網上的其他資料
我現在要做的就是用一下Dbfirst
項目右擊-->添加-->新建項-->實體數據模型
現在就會在項目中創建edmx文件和.tt文件
來看一下和剛剛生成的edmx文件有何區別
conceptialModels
Mappings
StorageModels
Designer
可以看到配置差不多,但是配置屬性值大都不一樣,主要是他們面向的對象不一樣,一個是面向數據庫的,一個是面向EF的
最後這個Designer我不理解,就當是學單詞了
在Designer配置中有個屬性CodeGenerationStartegy,一個是“None”,一個是“無”
那麽後一種是漢化投入較多的原因嗎?
我昨天就發現一個問題,就是我用DbFrist 生成了edmx文件,然後我來打印EF上下文提供的數據庫日誌,發現是中文的
using (EFDbContext ctx = new EFDbContext()) { ctx.Database.Log = msg => Console.WriteLine($"張四海-------------{msg}"); var stu = ctx.Students.FirstOrDefault(); Console.WriteLine(JsonConvert.SerializeObject(stu)); }
那麽我就猜想是DbFirst中漢化投入較多。因為它是可視化建模的,比如說我們安裝一個軟件會經常弄漢化包
但是為什麽Codefirst裏面又都是英文呢?應該就是本身可視化操作的東西就會對漢化有比較大的需求,而codefirst,全部是通過寫代碼來的,那這個需求就沒了。
現在來說說問題
在用Dbfirst的時候,肯定是對edmx這個文件非常熟悉,因為你可能會經常對它改動,因為所有的這些配置都是在這個文件中。
CodeFirst是較Dbfirs後出來的。那麽我學了那麽長時間的EF,怎麽覺得edmx(別人一說是EF的核心文件)一點存在感都沒有呢?
那是現在通過fluent API 或者DataAnnotations的方式,這個有形的edmx文件已經升華成了代碼。我就是這樣理解的。
那麽是不是edmx是不是就是作者說的預編譯視圖呢?
既然已經升華成了代碼,那就應該不需要edmx文件才對啊,怎麽又生成了一個呢?
繼續猜想,回到作者開頭說的一句話:當首次使用EF時,查詢數據的過程非常漫長,因為它必須生成用於計算要運行的查詢視圖。
那麽它是不是在運行時還是會根據代碼來生成一個內存化的edmx?雖然他沒有生成一個可見的edmx,但是在內存中,關於EF的那些配置、映射還是會構造、銷毀以此來完成
edmx那些配置的內容?
所以現在手動生成了edmx文件後,它就不會再 做這些工作了?
我的推理就到這裏了,我只能去這樣想了。那麽我得到的結果就是:edmx文件就是作者說的預編譯視圖。
那麽按照作者提供的方式,它生成的edmx文件只需要在放在項目文件目錄中就行了呀,為什麽還在Vs的安裝目錄下也會生成一個這樣的文件?
行吧,我覺得這裏我有點無能為力了。最後來看一下我們可以通過IO和EF提供的EdmxWriter對象直接將上下文寫入到一個XML文件,就是一個edmx文件
using (EFDbContext ctx = new EFDbContext()) { XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; using (XmlWriter writer = XmlWriter.Create(@"d:\Model.edmx",settings)) { EdmxWriter.WriteEdmx(ctx,writer); } }
EF6學習筆記三十:性能優化——預編譯視圖