Entity Framework 是微軟推薦出.NET平台ORM開發組件, 現在已放源代碼. 以下我們來討論一下優缺點和一些問題, 以下簡稱EF. 有興趣可查詢官網的Entity Framework 6 RoadMap.
高層視圖:
改變在現有系統使用EntityFramework的優勢是什么?
• All -in-1框架的類映射表,需要編寫映射代碼, 並且是很難維護的。
• 可維護性,易於理解的代碼,無需創造大的數據訪問層。
• 提供LINQ查詢數據庫,這需要從初級開發人員不太了解SQL。
• EF可以用作用於數據服務和OData Service的基礎設施。
什么的情況下,不建議使用EF呢?
• 實時的應用程序。
• 只能通過存儲過程訪問數據庫。 EF的優勢是:跟蹤實體狀態Change時,不僅僅在存儲過程上.(即使EF確實對存儲過程支持有限的)。
• 頻繁插入操作(Insert), 並且EF不支持大數據Bulk 插入。
• 頻繁更新操作,更新的目標主要是當多行(用一個單值)
例如:UPDATE 表名 SET ColumA = 10 Where ColumnB =?
這種更新操作更好的使用的ExecuteNonQuery(也可從Context上下文或直接從Ado.Net)。
• 反范式的表設計和高性能查詢。 EF產生查詢,他們是難以維護的,它並不能很好地支持映射到不規范的表。
• 對程序有非常的性能要求, 需要對每個查詢進行監控.
我們要在加載所有數據到內存中,建議使用實體框架? 我們應該期待什么樣的問題呢?
• 加載的所有實體將需要許多查詢和大量的時間。
• 內存開銷。
• 會有延遲,因為EF需要跟蹤實體的變化的和大Collection對象的處理。
• EF的Context上下文不是線程安全的,你不應該在整個Service上使用一個Context上下文。
• 如果你打算這樣做,使用EF加載實體,但並不管理它們. (Detach the entities從context)。
• 不使用的上下文Context對象作為一個緩存對象(用於分布式的情況下). 它不是線程安全的,有一些開支和不遵循分散關注(Separation of Concern)的設計。 更好的辦法是設計緩存API,如AppFabric緩存。
技術層面:
內存泄漏:
我們有這樣一個場景,每10秒我們打開Context上下文獲取一個單表,並關閉它。 “using (entities context = new entities(_connection)) {… ”
經過一段幾個小時,這引起了內存泄漏。
• 我建議你檢查內存泄漏,以確保它是從EF是根源。 EF是一個開源的,所以現在可以報告任何內存泄漏並修正它。
• 使用Profiler的VMMap,以便跟蹤泄漏的源頭。
在這種情況下,我們應該保持Context一直打開?
• 這其實並不重要,因為查詢仍然會執行。 然而,這是最好關閉Context下,所以緩存的實體將垃圾回收,否則Context和緩存的實體將在GC中升級到第二代,並且會被困在那里的持續一段時間。
• 不要為WCF每個請求創建一個Context上下文對象。
• 推薦的做法是為每次操作創建的Context對象,因為實體Item一旦被被添加到數據庫后就已經過時了,可能會導致數據損壞或重復的Item
EDMX的大小有影響嗎?
• EDMX影響的大小,因為所有的EDMX數據加載到內存中創建Context上下文。
• EDMX被加載到內存中,解析與映射在AppDomain中創建和緩存。 您可以關閉並重新打開Context,它沒有影響已緩存EDMX映射。
非常多的表
如果所有的表放在單個的EDMX或分別存放於幾個EDMX文件之間?
如何能管理的EDMX中大量的實體? 例如,如何可以找到它們?
在設計器中修改一個特定的表?
• 如果拆分之間edmx文件,你可以不連接實體的導航性能。
你應該建立自己的模型,根據您的實體模型設計 - 如果你有一組是獨立的實體,他們可以在不同的EDMX模型。
EDMX文件處理數百個實體類型。 如果實體類型的數量超過1000家,我會考慮到的幾個Edmxs(分開和重新審視自己的實體模型設計,因為成千上萬的實體類型的一個系統似乎太多)。
• 在VS 2012,以設計器的增強分解功能和着色等,請參閱以下鏈接。
• EF設計器有一些改進,如着色區分實體組的實體。
也有第三方實體的設計器,可能會得到更好的用戶體驗。
請記住 - EF是一個開源的,你可以給他們的要求,甚至貢獻自己的增加,所以在EDMX設計器探索很有趣的。
• 你應該按每個域/服務來拆分edmx文件到不同EDMX文件。
表之間關系
Lazy與No Lazy模式?
• 在分布式情況下Lazy代碼是魔鬼。
• 如果他們需要一組表中的數據,然后使用Include,否則,你可以使用Lazy Load模式
“Include”命令加載整個表或ObjectSet原始記錄?
• Include加載是相關實體的列。 EF不使用 * 查詢.
如何使用EF執行批量插入/更新操作?
• 做不到這一點,你需要使用原始的SQL語句來實現。
當一個實體被標記為已修改,EF更新的所有列?
• 它不更新所有的列,除非你正在使用分布式的應用程序與Self-Tracking。 “正常”實現下EF只更新修改列。 Self-Tracking不跟蹤的已更新的屬性,它標志着的所有屬性已更新。 您可以編輯Self-Tracking,並修復它,如果需要的話。
• 您可以附加一個SP以實現自定義的邏輯。
• 您可以更改T4模板的文件,在Self-Tracking下以保持所有原始值。
整個RAW更新的開銷大么?
• 大多數DB重新計算索引。 這是一個問題關系到DBA。
當我們使用EF為700-800KB的XML文件來更新XML列,我們收到了有關SQL Server的tempdb一個異常。 什么造成的嗎?
• 可能涉及到數據庫如何用臨時表來更新XML的內容。
應該和DBA檢查你的數據庫,你也許需要增加您的tempdb數據庫的大小。
• 在一般情況下, 大的對象,如XML使在GC的Large Object Heap內存的壓力,你應該考慮遷移到.NET 4.5版本的GC大型對象堆碎片整理特性。
• 你可以考慮來存儲XML為byte [],它可以被壓縮(XML不是一種非常經濟的格式)。
使用EF與ADO.Net的開銷?
• DataReader的結果變換到對象的開銷,從LINQ編譯SQL查詢的開銷。
您將有相同的開銷,甚至更多,如果您嘗試建立你自己的ORM框架。 不這樣做!
• 抽象層的開銷, 它取決於他們用EF所做的事情。
• 一般而言,您應該組合替代繼承,避免它有一個更大的開銷。
您可能感興趣的文章:
使用LINQPad調試Linq和Entity Framework
希望對您軟件開發有幫助.
作者:Petter Liu
出處:http://www.cnblogs.com/wintersun/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
該文章也同時發布在我的獨立博客中-Petter Liu Blog。