2012-02-23 103 views
5

我正在使用存儲庫模式,其中每個數據庫表有一個存儲庫類。我想知道你們如何處理,只有需要返回列特定數量的查詢存儲庫模式和返回類型

例如說我有以下

項目表(虛構表)

ItemId 
Name 
PurchaseDate 
Description 
Price 

在我代碼我創建了一個名爲Item.cs的字段(目前不使用orm)。

如果我有,我需要回到

  1. 項目Id
  2. 而purchaseDate和名稱
  3. 項目Id的組合多個場景和價格

這將是最好的方法?

  1. 獲取從項目表中的所有領域,並返回一個項目對象(1個回購查詢)
  2. 在回購創建三個查詢並返回一個項目對象爲每一個
  3. 在回購創建三個查詢和只返回需要什麼?

現在想象一下,這個場景有超過10個字段的表。

就我個人而言,我喜歡選項一,但我不確定是否有更好的方法來解決這個問題。

回答

6

我個人使用的通用型存儲庫,並有我的閱讀AsQueryable()

這裏的接口。

interface IRepository<T> 
{ 
    void Create(T item); 
    IQueryable<T> Retrieve(); 
    void Update(T item); 
    void Delete(T item); 
    void SubmitChanges(); 
} 

這裏是實施。

public class PersonsRepository : IRepository<Person> 
{ 
    private DataContext dc; 

    public PersonsRepository(DataContext dataContext) 
    { 
     dc = dataContext; 
    } 

    public void Create(Person Person) 
    { 
     dc.Persons.Add(Person); 
    } 

    public IQueryable<Person> Retrieve() 
    { 
     IQueryable<Person> Person = (from s in dc.Persons 
             select s); 
     return Person.AsQueryable(); 

    } 

    public void Update(Person Person) 
    { 
     Person _Person = (from s in dc.Persons 
          where s.ID == Person.ID 
          select s).Single(); 
     { 
      _Person.LastLogin = Person.LastLogin; 
      _Person.Password = Person.Password; 
      _Person.LastUpdate = Person.LastUpdate; 
      // Cannot change your username. 
     } 
    } 

    public void Delete(Person Person) 
    { 
     dc.Persons.Remove(Person); 
    } 

    public void SubmitChanges() 
    { 
     dc.SaveChanges(); 
    } 
} 

現在,如果您需要查詢存儲庫,您想要做這樣的事情。
原諒我,下面的代碼是未經測試,我其實更多的是VB傢伙:(
希望你明白了吧

public class PersonsService 
{ 
    private PersonRepository<Person> personRepository; 

    public PersonService() 
    { 
     personRepository = new PersonRepository<Person>(); 
    } 

    public UsablePerson GetPersonByID(int ID) 
    { 
     UsablePerson person = (from p in personRepository<Person>.Retrieve 
           where p.ID = ID 
           select new UsablePerson { p.FirstName, 
                 p.LastName, 
                 p.EmailAddress }).FirstOrDefault(); 

     return person; 
    } 
} 

對於我的目的,我使用LINQ在這個特別的項目,但這可以適應任何你喜歡的數據層...這是一個儲存庫層的美麗。

從這裏我「個人」也有一個服務層,處理數據連接的細微差別......像GetPersonByIDGetPeopleSince(DateTime marker)這是我去掉信息的地方我不需要(IE:密碼)並將其餘信息存儲在ViewModel或其他POCO中。

+0

只是爲了看看我是否在同一頁面上。對於像(GetPersonByID)這樣的更具體的查詢,您將從Repo中返回整個人員記錄,然後在服務層中刪除所有不需要的信息並返回該ID?你能舉出一個這樣的例子嗎,因爲這是我很難過的事情。我不確定我是否應該創建大量的Repo方法,或者只是有一個總是返回所有表列(即整行) – chobo 2012-02-27 17:57:12

+0

我盡我最大的努力從內存中...我沒有我的IDE在我面前所以在上面的例子中可能有一些錯誤。希望你能得到照片。 – 2012-02-27 18:28:50

+0

我喜歡這種技術,因爲它減少了存儲庫中的方法數量。但是,我總是被教導,你應該只從數據庫中返回你需要的列,看起來你在使用Repository時總是返回一個實體類型或實體集合。這是Repository模式的意圖嗎?也許我在考慮數據庫性能的影響 – chobo 2012-02-27 18:53:09

0

我喜歡基於Linq的倉庫這種事情。Linq2SQL,MSEF或Linq2NH將允許您通過Select()方法來定義列列表。然後,您將收到只填寫您指定內容的域對象或實體類。你可以有額外的代碼將其映射到DTO中,或者只是使用領域類知道它沒有完全「水合」。

2

如果您想到域驅動設計,單個對象具有不同配置的事實很可能表示不同的域。這並不需要每個對象都有不同的對象,但它是一個很好的模式。實現這一點的一種方法是擁有最簡約的一組屬性的基類。然後你創建更多的「特定於領域」的類從基礎繼承。對於返回數據,「流量複製」流程有多種方式。例如,多個存儲庫很好地區分了這些域。但是這增加了複雜性(除非絕對需要,否則不是一個好主意)。我不喜歡一個存儲庫返回不同的對象。如果你有一些可爲空的屬性(可能),這是更可接受的。

我不喜歡LINQ to SQL作爲DAL,正如@KethiS所建議的那樣,但我在企業環境中工作,而LINQ to SQL基本上是大規模的。使用LINQ否則很好。只是我的兩分錢。

如果您可以返回一個對象類型,那更好。如果對象中的差異基於權限,請考慮清除用戶不應看到的數據。但是,請注意,如果抓取大量對象,則這不具有可伸縮性。

+0

+1不錯的答案。 – jgauffin 2012-02-23 19:05:26

+1

我傾向於只從回購中返回一個對象類型,但是讓我絆倒的是我應該總是返回一個實體對象?例如,如果我有一個名爲GetEmployeeID的方法,我應該只返回一個Employee對象與該字段嗎?或者我應該只返回一個員工號碼?我應該只使用getEmployee方法,還是應該將這些方法分解爲Repo中更具體的方法,比如GetEmployeeId和始終使用GetEmployee? – chobo 2012-02-27 17:59:53

5

當我需要它們時,我將方法添加到我的存儲庫,與通用存儲庫相比,無論您是否需要它們,您都可以獲得一組方法。

返回IQueryable是一個漏洞抽象。

看看Domain Driven Design(這本書),你會明白設計良好的存儲庫應該是什麼樣子。

我也寫一個關於通用倉庫的咆哮:http://blog.gauffin.org/2012/02/generic-repositories-a-silly-abstraction-layer/

+0

同意,返回'IQueryable'與您想要存儲庫執行的操作完全相反 - 這只是將基礎結構關注回到您的域層。 – davenewza 2014-10-08 17:52:59

0

你爲什麼會返回所有字段,當你真正需要只有少數?如果擔心表現,請選擇您真正想要的字段。我不是嚴格遵循設計模式的忠實粉絲,也許你應該考慮根據你的要求改變設計。