本文章是由機器翻譯。

資料點

Julie Lerman

我曾與很多客戶,以説明重構現有的軟體,它使用Entity Framework(EF)。在 EF 代碼重構可以有多種含義往往與更新。在本專欄中,我會看看的一些方法你可能會檢修 EF 代碼或涉及 EF 的應用程式。對於每個這些方法,我會提供一些指導 — — 我與客戶的生產應用程式工作的經驗的基礎 — — 那應該説明您做好充分準備,避免有些頭疼。

我將討論的改變有:

  • 更新到新版本的Entity Framework
  • 分手大型Entity Data Model
  • ObjectCoNtext API 替換 DbCoNtext API

我會涵蓋這個月的前的兩個在高級別,然後跟進在我下一列由挖到的最後一個假想的指導,以及一些具體的例子。

你踏上任何這些任務之前,有的意見我強烈建議您按照初始位:做他們一一次。我已經在包括一個舊的專案,它使用 EF4,一個巨大的模型和 ObjectCoNtext API 的努力一部分。試圖更改所有三個在同一時間只能導致淚水和挫折 — — 和,也許更糟。在這種情況下,我建議的課程是第一次更新的 EF 版本而不進行任何其他更改,然後確保一切都繼續工作。下一步涉及查明的可以提取到一種新的小模型的模型區域。但是,最初,我讓繼續將目標 ObjectCoNtext API 的新模型。當一切回到工作訂單,轉移到 DbCoNtext API 已啟動,但是只為那小模型。否則為太多的東西能打破整個應用程式,你會追捕的 bug 的各種野生、 非相干的使命。通過將一個小模型轉移一次,你有破碎的代碼要返工的較小的表面區域,您可以瞭解一些好的經驗教訓和模式,將使轉移更少痛苦的下一個小模型。

更新為較新版本的Entity Framework

由於 EF 團隊重點向後相容性,從一個版本移動到另一個提供最低限度的摩擦。我將重點介紹更新到 EF6 — — EF6,以及其未成年的更新,如 EF6.02 和 EF6.1 的主要版本。

最糟糕的問題以移動從 EF4,EF4.1 或 EF5 EF6 (這在我看來,真的不是太壞) 的變化造成的一些命名空間。因為原始 Api 是仍在 Microsoft.NET 框架中,讓他們在 EF6 中重複會導致問題。所以在 EF6 API 中,這些類是命名空間中是不同的 System.Data 以避免衝突。例如,當地有很多中的命名空間。基於網路 EF 開始與 System.Data.Objects、 System.Data.Common、 System.Data.Mapping、 System.Data.Query,以及幾個其他的 Api。也有一些類和枚舉的直接生活在 System.Data ; 例如,System.Data.EntityException 和 System.Data.Entity­狀態。大多數的類和命名空間,直接綁 System.Data 以這種方式被移到新的命名空間根,System.Data.Entity.Core。有少數幾類移到 System.Data.Entity,如 EntityState,在 System.Data.Entity.EntityState 現在發現。例如,映射的命名空間是現在 System.Data.Entity.Core.Mapping,而物件命名空間現在是 System.Data.Entity.Core.Objects。見專案 4 在資料開發人員中心文檔中,"升級到 EF6"(bit.ly/OtrKvA),具體的異常的沒有進入 System.Data.Entity.Core。

當更新現有應用程式到 EF6,我只是讓編譯器顯示我的任何"的類型或命名空間...未找到"錯誤,從而突出顯示所做的更改,然後我做一些解決方案範圍查找和替換為正確的命名空間。

作為一個例子,我開始與小示例解決方案從第二版的我的書,"程式設計Entity Framework"。這種解決方案是使用 EF4、 EDMX 模型、 生成代碼的 POCO 實體類和 ObjectCoNtext API 編寫的。第一次代碼和 DbCoNtext API 時,並不存在。在我開始之前,我已驗證應用程式仍然工作 (Visual Studio2013年中調試)。

雖然我專注于一個更大的飛躍 — — 從 EF4 到 EF6 — — 您需要遵循相同的路徑的命名空間修復如果你去從 EF5 EF6,因為這些命名空間更改 EF5 和 EF6 之間發生。直接向 EF6 從 EF4 移動了幾個額外的挑戰,再加上我老的解決方案使用 T4 範本不具有直接替換。

我從 EF4 到 EF6 步驟更新

如果你習慣了Entity Framework使用 NuGet 包分發,你會需要想回到時間 EF 只是.NET 框架的一部分,時其 Dll 的所有住在 Windows 全域組件快取 (GAC)。更新到 EF6 之前, 我手動刪除對 System.Data.Entity (版本 4.0.0.0) 的引用中的每個我的解決方案的專案。我也清理解決方案 (通過按右鍵解決方案資源管理器中的解決方案並選擇清理解決方案) 可以肯定的任何原始 Dll 到 BIN 資料夾可能不得不走了。原來我的勤勉不是必要的因為 EF6 的 NuGet 包安裝程式為您刪除舊的引用。

然後我使用 NuGet 安裝 EF6 納入有關專案,並重新生成解決方案。您自己的解決方案中的專案依賴項將磁碟機命名空間問題表面的速度有多快。我的解決方案,我只顯示了一個命名空間錯誤在第一次。我固定的和重新生成解決方案,然後看到許多更多的錯誤 — — 只有一個是命名空間的問題。對於一個異常,編譯器提供有用的消息,告訴我一個不太常用的屬性已採取優勢 (EdmFunction) 經歷了名稱的更改 (和因此被標記為已過時) 和已改為 DbFunction 屬性。

在一系列反覆運算的命名空間的修復和重建,花了幾分鐘才為此小的解決方案以後, 我是能夠成功地生成和運行應用程式 — — 查看、 編輯和保存資料。

修復 ObjectCoNtext Plus POCO T4 範本

有一個其他可能的任務,要牢記。我的解決方案使用 EDMX — —Entity Data Model設計和保養與 EF 設計器。因為我在 EF4Visual Studio2010 中創建的它依賴于舊的代碼生成範本,生成的 ObjectCoNtext 來管理所有的資料緩存和持續存在。該範本從模型中的實體生成的 POCO 類 (它們具有Entity Framework框架沒有依賴項)。如果我對我的模型進行任何更改,我需要重新生成類和上下文。但該舊範本 — — 生成上下文的那個 — — 還不知道新的命名空間。雖然有 DbCoNtext 範本和 ObjectCoNtext (加 EntityObjects) 範本 (見圖 1),那裡是沒有替換為我提供的 ObjectCoNtext 加思卡爾組合的範本。並以使事情更有趣,我定做了我所使用的範本。所以而不是選擇一個新的範本,不會與我的應用程式的工作,我向兩個小變化存儲在現有解決方案中的 CoNtext.tt 範本:

  1. 在行 42,"System.Data.Objects ; 使用"成為"使用 System.Data.Entity.Core.Objects ;"
  2. 在行上 43,"使用 System.Data.EntityClient ;"變得"使用 System.Data.Entity.Core.EntityClient ;"


圖 1 你會發現範本生成 DbCoNtext Plus 思卡爾或 ObjectCoNtext 加非-思卡爾。

現在,我重新生成從模型中,類的任何時間的 ObjectCoNtext 類會得到正確的命名空間,我自訂的 POCO 生成的類將繼續在我的應用程式功能。請注意我前面提到的資料開發人員中心文檔介紹了如何使用支援的範本。

你會得到而無需更改任何更多的代碼的好處

更新應用程式以使用 EF6 漂亮無痛找到然而,有一點非常重要,以考慮。當應用程式現在使用的是最新版本的Entity Framework,它受惠只能從根本改善Entity Framework— — 特別是一些大的性能提升在 EF5 和 EF6,來。因為大部分的這些性能增益進來 EF5,從 EF5 到 EF6 沒有利用的其他新功能不會產生多少影響。來看看還有什麼 EF6 中的新功能,請查閱我 2013 年 12 月的文章,"Entity Framework6:忍者版"(bit.ly/1qJgwlf)。許多方面的改進是 DbCoNtext API 和代碼第一次的相關的功能。如果您想要更新到 EF6 和也更新到 DbCoNtext,我建議從開始,簡單的升級到 EF6,並得到一切再次工作轉移到 DbCoNtext API 在開始之前。這是我掩護詳細地在我的下一篇專欄文章更複雜變化。

即使有這些可能最小的變化,您的代碼庫是現在準備利用更加現代的 Api。

分手大型模型

你是否用的 EF 設計器來創建您的模型或代碼第一次工作流 (請參見"DemystifyingEntity Framework戰略:模型創建工作流"在 bit.ly/Ou399J),與他們中的許多實體模型會導致設計時和運行時甚至問題。我個人的經驗是大型模型只是太笨重,難以維持。如果您使用設計器,並有許多實體 (數百個),不僅較長的設計器打開並顯示該模型,很難直觀地導航模型。值得慶倖的是,設計器獲得了一些偉大的Visual Studio2012年中的功能,可説明 (請參閱"Entity Framework設計器Visual Studio中獲取一些愛 2012"在 bit.ly/1kV4vZ8)。

即便如此,我總是建議模型會更小。我在列中,"收縮 EF 模型與 DDD 界上下文"(bit.ly/1isIoGE),我談到更小的模型,以及一些戰略為在您的應用程式中使用它們的好處。如果您已經有一個大的模型,然而,它可以是一個挑戰,要分開的。正在與他們進行逆向工程從 700 或甚至 1000 實體結局的龐大資料庫模型的用戶端了是否你縮水 EDMX 模型在設計器中或使用代碼第一,這個故事是相同的:分手是難做的。

這裡有一些有用的線索為分手大型模型成更小的模型更簡單維修保養和運行時性能可能會更好。

Don不嘗試一次重構整個模型。為您提取每個小模型,你需要做一些額外的代碼重構因為引用更改和你可能有一些關係代碼,以及糾纏。

所以第一步是模型的確定是模型的近自主的一段。Don起初擔心的重疊。例如,你可能會在系統上工作一家生產和銷售產品的公司。本軟體可能包括一項功能,維護您的銷售人員 — — 的人員資料,聯繫資訊,銷售領域等等。該軟體的另一部分可能會引用這些銷售人員構建基於您銷售界的定義的用戶端的命令時。但另一部分可能會跟蹤其銷售傭金。所以對付一個特殊的方案 — — 說,保持銷售人員名單 — — 一次。

這裡是轉移到更小的模型的步驟:

  1. 確定該方案中涉及的實體 (見圖 2)。
  2. 創建一個完全新的專案。
  3. 在該專案中,定義一個新的模型 (無論是與 EF 設計器或使用代碼第一次) 這就是意識到相關實體。
  4. 標識應用程式代碼所涉及的產品維護。
  5. 更新使用原來的上下文的相關代碼 (查詢、 保存更改或其他功能) 使它使用新的上下文,您已經創建。
  6. 重構現有代碼,直到目標功能工作。如果你有自動化測試在的地方,這可能會使重構的任務更有效率。

一些額外的諮詢意見,在此過程中要牢記:

  • 從大模型不刪除這些實體。這樣做會導致很多事情要打破。只是把他們留在那裡,現在忘了他們。
  • 保留什麼樣的重構你不得不做才能使應用程式與新的小模型工作的日誌。


圖 2 銷售人員和領土維護可以提取到一個單獨的模型與其他實體對影響很小

您將學習可以按照您繼續打破其他重點從大模型模型應用的模式。

通過反覆運算一次向解決方案中添加一個新的小模型和指揮的代碼來使用它,你的經驗會愉快得多。在大模型中,可能會在無事可做,銷售人員維護任務的關係亂麻這些相同的實體。例如,你可能會有從銷售人員的銷售訂單的關係,所以你大概不會想要從模型中完全移除銷售人員。它是簡單有裁剪下來,唯讀銷售人員類型順序創建在一個模型,然後全面爆發可編輯銷售人員類型 (與無知識的訂單) 用於另一個模型中的維護期間用作參考。當所有都完成時,這兩個實體可以繼續指向相同的資料庫。如果您正在使用的代碼第一次和遷移,請檢查上述第條有關收縮 EF 模型共用一個資料庫,當您有多個重疊模型的指導。

你可能最終與許多小模型和仍然對大模型的某些引用。此時,它將更容易地識別哪些實體不再碰大模型中,可以安全刪除。

耐心:是的它是一種美德

最重要的外賣是接近這些更新和將重構在小口小口和每次反覆運算時,讓您的測試和應用程式在移動上前再次運作。考慮到較新版本的Entity Framework作為自己的工作項更新。甚至可以將拆分為兩個當你第一次集中在拉扯中較新的 Api 和確保您的代碼將繼續運行在更改代碼以利用新功能之前。寶寶的相同步驟適用于分手大模型 — — 尤其是如果你打算從 ObjectCoNtext 到 DbCoNtext 更新。提取小模型和重構,以確保有關邏輯可以起作用的新的小模型。那工作後,它是你斷交的 ObjectCoNtext,將在第一次打破一堆代碼的時間。但至少破壞的代碼將被隔離到較小的區域,您的代碼庫的你會一次重構代碼更少。

在我下一列中,我會深入到更痛苦,但完全可以實現的目標移動 ObjectCoNtext 代碼使用 DbCoNtext API。

Julie Lerman 是微軟最有價值球員,.NET 的導師和諮詢師,住在佛蒙特州的山裡。你可以找到她提出關於資料訪問和 other.NET 在使用者組和世界各地的會議的主題。在她博客 thedatafarm.com/blog 和的作者是"程式設計Entity Framework"(2010 年) 以及代碼第一版 (2011 年) 和 DbCoNtext 版 (2012 年),所有從 O'Reilly 媒體。跟著她在 Twitter 上 twitter.com/julielerman 看看她的 Pluralsight 課程 juliel.me/PS-視頻

感謝以下 Microsoft 技術專家對本文的審閱:羅恩Miller