2010-04-09 157 views
3

我正在使用存儲庫模式與LINQ到SQL,我使用每個表的存儲庫類。 我想知道,我是在做的好/標準的方式,Linq到SQL存儲庫模式,一些問題

ContactRepository

Contact GetByID() 
    Contact GetAll() 

COntactTagRepository

List<ContactTag> Get(long contactID) 
List<ContactTag> GetAll() 
List<ContactTagDetail> GetAllDetails() 

class ContactTagDetail 
{ 
    public Contact Contact {get;set;} 
    public ContactTag COntactTag {get;set;} 
} 

當我需要一個接觸我調用方法contactrepository,同爲contacttag

但是當我需要聯繫和標記在一起時,我在ContactTag存儲庫中調用GetDetais()它不返回COntactTag實體由orm生成insted其返回的ContactTagDetail實體conatining由orm生成的COntact和COntactTag,我知道我可以在COntactTag存儲庫中簡單調用GetAll並可以訪問Contact.ContactTag,但作爲它的LINQ到SQL它將沒有選項延遲加載在查詢級別,所以每當我需要一個實體與相關實體我創建了一個投影類

另一個疑問是我真的需要權利的方法我能做到這一點在雙方接觸& ContactTag repostitory像在接觸庫GetALlWithTags( )或其他東西,但我在做COntactTag存儲庫

你的建議是什麼?

回答

5

我沒有時間詳細說明,但基本上沒有表和存儲庫之間的一對一關係。我犯了這個錯誤,但它不起作用。相反,讓您的存儲庫包含所有與概念相關的表。在你的情況下,只需要一個處理聯繫人和聯繫人標籤(以及任何其他相關表)的聯繫人存儲庫。沒有關於「相關」意味着什麼的規定,只有您可以決定 - 但是基於您理解應用程序的元素如何自然組合在一起來管理您的決定。

也對,這樣處理類似的問題這兩個線程的讀:

Multiple or Single Repositories with LINQHow to use the repository pattern correctly?

+0

其良好的,但是當我有很多相關的實體庫,在這裏,我會寫的插入/刪除等方法, – MindlessProgrammer 2010-04-09 20:19:19

+0

你可以將它們全部放在一個存儲庫中,只要它們作爲「工作單元」相關聯即可。 – 2010-04-09 20:33:58

-1

我相信你是在正確的軌道上。 linq to sql遇到的一個問題是與表格一對一映射。所以你不得不向你展示許多關係表。

我得到解決這個問題的方法是使用一個數據層有權訪問linq到sql,但在返回調用之前將所有內容映射回POCO對象。

public IQueryable<ArtGalleryData.Image> GetImagesByImageGroup(int id) 
    { 

     return SqlDataContext.Image_ImageGroups 
      .Where(iig => iig.ImageGroupID == id) 
      .Join(
      SqlDataContext.Images, 
      iig => iig.ImageID, 
      i => i.ImageID, 
      (iig, i) => new ArtGalleryData.Image 
      { ImageID = i.ImageID, 
       Description = i.Description, 
       Title = i.Title, 
       Height = i.Height, 
       Width = i.Width }).AsQueryable(); 
    } 

基本上我映射LINQ對象圖像返回到POCO對象圖像。 (我知道它的一種凌亂,但它是我手頭上的最好例子。)

要獲得延期加載的效果,您將返回一個IQueryable <T>對象。這將允許您在執行查詢前暫緩執行,直到需要爲止。通過IQueryable的<收藏LazyList它允許延遲加載(延遲執行)筆>

大部分我所知道的是從閱讀羅布Connerys:

而且在他們依賴的集合對象,我發現這個偉大的助手類博客MVC Store Front

閱讀他的博客文章並下載商店前臺項目我認爲它會回答你的許多問題。如果你不使用asp.net MVC只是查看他的數據訪問層應該是一個巨大的幫助。

希望可以幫助

+1

羅布·康納利不是羅比·科裏 – 2010-04-10 19:54:19

+0

哎呦,謝謝我會更新我的作品 – Anthony 2010-04-11 19:03:08

+0

-1不要暴露泄漏的'IQueryable '。 – jgauffin 2013-05-20 15:34:37

1

這不是存儲庫模式。存儲庫模式基本上是通過將(在概念上)作爲域中特定類型的所有對象的集合進行操作來創建一個抽象出持久性的對象。

因此聯繫人存儲庫可能工作是這樣的:

IContacts contacts = GetContactRepository(); 
using(var uow = UnitOfWork.Create()) { 
    var contact1 = contacts.Get(new FindByNameSpecification("Fred")); 
    contact1.LastName = "Rubble"; 
    var contact2 = new Contact("Barney", "Flistone"); 
    contacts.Add(contact2); 
    // both contact1 and contact 2 are implicitly saved at the end of the unit of work 
} 

如何倉庫應該工作可能是這樣一個稍微寬鬆的定義:

IContactRepository contacts = GetContactRepository(); 
using(var uow = UnitOfWork.Create()) { 
    var contact1 = contacts.GetByName("Fred"); 
    contact1.LastName = "Rubble"; 
    contacts.Save(contact1); 
    var contact2 = new Contact("Barney", "Flistone"); 
    contacts.Save(contact2); 
} //The save is explicit but the commit is implicit 

你有什麼一個table data gateway

問題是您正在爲每個表格創建一個網關。我會建議反對。

是否標記您的聯繫人域的一部分?如果是,那麼你應該具有的屬性

public class Contact { 
    public IEnumerable<Tag> Tags { get; } 
    public void TagWith(Tag tag) { .... } 
    public void UnTag(Tag tag) { ... } 
} 

另外,問一下自己,你永遠不會添加具有其下的零個接觸標籤?如果沒有那麼它變得更簡單 - 你不需要網關來管理所有的標籤,只是讓你的聯繫對象處理它

public interface IContactRepository { 
    IEnumerable<Contact> GetAll(); // returns Contacts along with their tags 
    void Save(Contact); // saves Contact along with any tags 
} 

順便說一句,如果標籤是不是你的域的一部分(如在它是一個應用程序所關注的),那麼你應該有一個單獨的服務,甚至可能在一個單獨的項目

public interface IAssociateTags { 
    IEnumerable<Tag> GetTagFor(Contact contact); 
    void TagContact(Contact contact, Tag tag); 
    void UnTagContact(Contact contact, Tag tag); 
}