首先,遵循什麼弗蘭克Schwieterman說。讓您的存儲庫隨着其使用量的增長而增長。另外,瞭解並使用IQueryable接口。 L2S,Entity Framework,LINQ to nHibernate,以及一些較新的ORM(如SubSonic和Telerik的ORM)都支持IQueryable接口。
在您需要存儲庫中的可變查詢但仍希望交換OR映射器(如果需要)的好處的情況下,IQueryable是一個強大的工具。假設如下:
public class ProductRepository: IProductRepository
{
public Product GetByID(int id);
public IList<Product> GetAll();
public void Insert(Product product);
public Product Update(Product product);
public void Delete(Product product);
}
這是一個相當常見的存儲庫,只有普通的方法。隨着時間的推移,你最終可能會和一幫更多的方法:
public IList<Product> GetByOrder(Order order);
public IList<Product> GetByCategory(Category category);
public IList<Product> GetByQuantityInStock(int quantityInStock);
這也是很常見的,取決於你怎麼樣來解決這個問題,完全可以接受。但是,從長遠來看,您的存儲庫可能會變得笨重,其界面將一直在變化。你也失去了在幕後使用OR映射器的真正好處。
你可以保持原始的,簡單的存儲庫接口,但仍然提供了自己一個很大的靈活性,如果你改變了一個方法:
public IQueryable<Product> GetAll();
你的庫現在返回查詢,而不是已經列表檢索的對象。現在,您可以自由使用該查詢像任何其他支持LINQ對象:
var productsWithLowStock = productRepository.GetAll().Where(p => p.Quantity < 10);
var orders = orderRepository.GetAll();
var productsWithOrders = productRepository.GetAll().Where(p => orders.OrderLines.Any(ol => ol.ProductID == p.ProductID));
一旦你開始使用的IQueryable接口與你的資料庫,您獲得兩全其美的:在你的下級數據A mockable抽象訪問以及代碼中動態查詢的功能。你可以把這個概念做得更遠一些,並創建一個基本的Repository類,它實現了IQueryable本身,允許你消除對GetAll()調用的需要,並且直接查詢存儲庫(雖然具有其他複雜程度)。
這種方法遇到的問題是何時調用dispose。出於這個原因,我通常有兩個存儲庫接口,一個是IQueryable類型訪問器(支持IDisposeable,其生命週期必須由調用者管理),另一個用於寫入或其他複雜操作,其中每個調用在內部使用一個數據上下文。 – 2009-10-16 22:26:56