まず、Frank Schwieterman の発言に従ってください。使用量の増加に合わせてリポジトリを拡張します。さらに、IQueryable インターフェイスについて学び、それを利用します。L2S は、Entity Framework、LINQ to nHibernate、および SubSonic や Telerik の ORM などの一部の新しい 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 マッパーを使用することの真の利点も失います。
元の単純なリポジトリ インターフェースを維持できますが、メソッドを 1 つ変更すると、多くの柔軟性が得られます。
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 インターフェイスの使用を開始すると、両方の長所を活用できます。下位レベルのデータ アクセスに関するモック可能な抽象化と、コード内の動的クエリの機能です。この概念をもう少し進めて、IQueryable 自体を実装するベース リポジトリ クラスを作成すると、GetAll() 呼び出しの必要がなくなり、単純にリポジトリに直接クエリを実行できます (複雑さは増しますが)。