19

存儲庫模式用於從特定數據庫和對象關係映射技術(如EF)抽象使用。因此,如果我決定這樣做,我可以很容易地將(例如)我的Entity框架映射替換爲Linq to SQL。存儲庫模式與實體框架

但是,當我使用EF我有我的實體類從模型 - 也就是他們從該視覺圖生成。如果我在存儲庫中使用這個生成的實體類,然後決定用其他東西替換EF,那麼我將刪除該可視化實體圖,這意味着還要刪除類嗎?

我正在處理的一點是,我的存儲庫將依賴實體框架,即在數據訪問層上,因爲它將使用由EF生成的類。

我該如何消除這種依賴性?

另請注意,我主要使用EF是因爲它能夠從該視覺圖生成所有內容 - 我只是設計圖並讓它爲所有外鍵生成數據庫等。我非常喜歡這一點,不想考慮SQL命令。

回答

27

存儲庫始終依賴於數據訪問技術。這就是人們使用存儲庫的原因 - 將數據訪問依賴關係包裝到單獨的圖層。如果你決定改變數據訪問技術(你可以做1%的機會),你將不得不創建新的存儲庫,實現與以前相同的界面。

介紹repositoris將增加一個新的複雜層。存儲庫有其優點和缺點。只是因爲「你可以改變未來的數據訪問方式」而引入它們是一個不好的理由。不要因爲可能發生的事情而設計你的應用程序。根據當前實際需求設計應用程序(敏捷方式),並在需要更改時重構代碼 - 這是如何在市場上具有競爭力的唯一方法。功能是銷售你的軟件而不是其開放式架構,用於任何類型的變更(好吧,有例外,但在這種情況下,開放架構是最高級別的要求)。

當使用EF可以有幾種選擇如何創建實體:

  • 使用對自定義工具來生成實體對象。這是爲EDMX創建「代碼隱藏」文件的默認方法。它是EFv1(.NET 3.5 SP1)中唯一可用的解決方案。
  • 使用T4模板來生成實體對象,POCO,STE或任何自定義實體類型(您可以修改生成邏輯)。這通常用於EFv4。
  • 自己寫POCO。這可以與EFv4一起使用,並且它始終與EF 4.1中的代碼優先方法一起使用。

如果您希望數據訪問技術在未來可以改變,可以使用POCO的第二種或第三種方法。在T4模板的情況下,您可以簡單地複製生成的POCO或修改項目文件,以便在刪除EDMX文件後不會丟失它們。

如果你是不知道,如果第二或第三種方法適合你看看我這些問題的答案:

因爲我不知用@ Patko的答案同意你還應該檢查Ayende's blog。他已經寫了幾篇關於使用存儲庫和構建應用程序的文章。他正在撰寫有關NHibernate的文章,但是可以使用EF進行類似的裁決。唯一的區別是NHibernate提供了更好的抽象,所以直接使用NHibernate的代碼更好的可測試性。

+0

@Ladislav Mrnka首先我不同意「不要設計你的應用程序,因爲可能發生的事情」。我總是試圖使我的代碼更加健壯和防守,並且通常會在以後證明這是一個很好的決定。幾乎沒有多餘的行意味着在重構和調試時節省了數小時。如果「由於可能發生的事情而不設計你的應用程序」是真的,那麼許多項目根本不會使用存儲庫(除了那些需要從一開始就支持2種永久存儲技術的應用程序之外)。其次,我只是感覺不好,因爲我需要一些DAL來包裝它。 – drasto 2011-03-23 09:05:00

+0

@Ladislav Mrnka +1爲T4模板和這些鏈接。有關於此的更多資源? – drasto 2011-03-23 09:12:40

+1

@drasto:如果你足夠熟練地對你的架構做出專業決定,那麼這種方法就沒問題。但是在回答和閱讀許多有關EF和知識庫的問題之後,我只是認爲許多開發人員都在構建他們的應用程序。從一開始就有兩種數據訪問技術是引入存儲庫的一個很好的理由,但您在問題中沒有提到它。 – 2011-03-23 09:15:37

3

實體框架版本4的一個新功能是「Code First」開發。這將允許您在實體框架中使用常規的C#(POCO)類。一旦以這種方式編寫了類,就可以編寫一個不同的存儲庫實現,它們使用不同的機制來保存這些類。

ScottGu有一個blog post包含更多信息。

+1

其實這是不EFv4的特徵。它是獨立的版本,稱爲EF 4.1。 – 2011-03-23 08:11:47

+0

+1我喜歡。不僅因爲擁有獨立的類,而且還因爲每當我對模型類進行更改時都可以重新創建數據庫。但是有一些東西我不喜歡 - 這是不必編寫的所有類和它們的屬性 - 我希望我的模型有大約50-70班。在視覺設計師看來好多了。所以,我希望這樣的事情「1.創建可視化模型圖2.擁有VS產生從圖3有無EF POCO類來生成表從POCO類外鍵等,或(甚至更好)有一些其他的工具生成EF圖POCO clases」 – drasto 2011-03-23 08:27:23

+0

@drasto - 與EF的設計師一種常見的批評是它是如何與笨重量好實體使用。奇怪你有相反的問題。 @Sean Reily - 你的回答是不正確的。 4.1中的「代碼優先」並不支持您使用POCO類,這在4.0中是可能的。 MS後來發佈了t4模板,使這更容易。 http://visualstudiogallery.msdn.microsoft。com/23df0450-5677-4926-96cc-173d02752313 – jfar 2011-03-23 12:31:45

7

從一種持久性技術轉換到另一種持久性技術的能力很好,而且都很好,但是你真的需要嗎?

首先,什麼是存儲庫?它提供了對域對象的內存中類似集合的訪問。但是每個現代的ORM工具都已經這麼做了,所以另一個抽象層次就增加了一些複雜性。其次,從一種持久性技術切換到另一種持久性技術通常比提供另一種庫實施更復雜。例如,你打算如何處理交易?事務通常依賴於上下文,並在倉庫之外處理。您當然可以使用某種工作單元實現,但是您必須爲每個持久性技術實現新的工作單元。

我不是故意說你不應該使用存儲庫,只是可能給它另一個想法。

+0

我仍在考慮我的選擇。我有ASP.NET MVC應用程序,其持久性只是想工作......它設計得很糟糕。所以我必須從頭開始重新構建它,以便能夠根據開發業務邏輯需求(我現在正在開發的)開發輕鬆更改模型。那麼你建議我做什麼?我應該只是將'ObjectContext'的實例傳遞給服務層中的服務?我覺得有點不好... – drasto 2011-03-23 09:14:07

+2

+1,因爲我同意它。倉庫被過度使用,並且在任何現代ORM工具存在之前就定義了它。 – 2011-03-23 09:19:53

+3

也許你可以看看Ayende的博客http://ayende.com/Blog/default.aspx。他是存儲庫模式的支持者之一,但他改變了主意。它從http://ayende.com/Blog/archive/2009/04/17/repository-is-the-new-singleton.aspx博客文章開始。他的最新帖子也提供了一些關於如何去做的想法。至於'ObjectContext',我不明白爲什麼不。如果你通過知識庫會感覺好點?只要看看'ObjectContext'作爲一種存儲庫:) – Patko 2011-03-23 09:23:04

6

EF設計者創建的實體類在您的項目中,在您的「Model.Designer.cs」中。您可以複製代碼,以便您的實體保留在您的項目中,即使您從EF中刪除模型或引用。 但是,它們與EF緊密耦合,因此您應該努力將EF從實體類中解耦。

到現在爲止,你有T4模板,可以幫助你的脫鉤,但他們仍然需要一些改變選擇的T4:

  • ADO.NET EntityObject生成
  • ADO.NET POCO實體發生器
  • ADO.NET自跟蹤實體發生器

EF4.1帶來了一個簡化的API,DbContext,可以在您想要分離實體類時提高EF的體驗。用EF4。1你的方法3:

  • 代碼首先
    • 您創建的類和EF創建DB,因爲它應該是
    • 類不會自動消失,當你刪除對EF
    • 引用
    • 你不會有任何設計師
  • 數據庫優先
    • 如果你已經有一個數據庫,模型會爲您創建設計者
    • 您可以用新的T4模板創建自己的實體類的DbContext發電機
  • 機型第
    • 如你現在已經做的那樣,你在設計器中創建你的模型
    • 你可以用DbContext生成器創建實體類

現在回答你的問題:

如何刪除這種依賴?

  1. 安裝EF4.1
  2. 創建模型(使用模型第一種方法)
  3. 從模型生成數據庫
  4. 用的DbContext發電機

生成實體類看看你如何在這裏做到這一點:EF 4.1 Model & Database First Walkthrough
你應該閱讀ADO.NET團隊博客Using DbContext in EF Feature CTP5 Part 1: Introduction and Model(EF4.1前身爲EF功能CTP5)系列。
你可以在我的問題更多的細節:EF POCO code only VS EF POCO with Entity Data Model

+0

+1現在你是這裏的明顯贏家。我決定使用T4模板來生成POCO實體,然後嘗試找出當我更改模型時如何使框架自動重新創建數據庫表。不過我更喜歡你的建議 - 看起來用簡化的API然後用T4模板做起來更容易。我還有一個問題:在使用Model First方法時,每次更改我的模型時是否可以讓我的數據庫表與POCO類一起自動重新創建?我該怎麼做 ? – drasto 2011-03-23 18:32:30

+0

我知道代碼第一種方法可能自動生成表格代碼第一種方法 – drasto 2011-03-23 18:40:40

+0

我已經問過你的答案在這裏受到啓發的另一個問題,請隨時張貼一些答案http://stackoverflow.com/questions/5410381/generate-poco-classes -from-model-using-t4-templates-vs-ef4-1-simplified-api-mode。無論如何謝謝 – drasto 2011-03-23 19:28:03