2012-05-04 5 views
0

私は3層のASP.NETアプリケーションを持っていますUIサービス層リポジトリです。サービスレイヤメソッドでIQueryableをパラメータとして渡すのは良い方法ですか?

私は検索機能をデータベースの製品に実装する必要があります。 ProductRepositoryは私のリポジトリクラスであり、データベースからすべての製品を取得するメソッドのシグネチャは次のとおりです。

サービスレイヤ私が使用からそのため
IQueryable<Product> GetAllProducts(); 

IProductRepository _ProductRepository = new ProductRepository(); 

IQueryable<Product> products = _ProductRepository.GetAllProducts(); 

例えば> 100の商品を服用するなど、IQueryable<Product> productsをフィルタリングしたい場合、またはの色= "黄色"のもの。

だから私は代わりのようなProductRepositoryのメソッド作成するので、思っていた:私のサービス層にようIQueryable<Product>を受け入れるメソッドのセットを作成することをお勧めしている場合、私は思っていた

IQueryable<Product> GetAllProductsByColor(int colorId) 

をパラメータ直接そこフィルタリング実行:Dictionary<string, string>(プロパティ名、値)との組を表す

IQueryable<Product> FilterProducts(IQueryable<Product> products, Dictionary<string, object> filters) 

を。

このソリューションの利点は、複数のフィルタを適用する必要がある場合、フィルタ処理された製品セット間の交点を毎回取るのではなく、すでにフィルタリングされたIQueryable<Product>を渡すことです。

のコンテキストを開いたままにしておくか、多層アーキテクチャで「許可」しないとよいでしょうか?

答えて

2

私は、あなたのIQueryableの実装を提供するものに依存していると思います。ほとんどの場合、IQueryableのユーザーは、1)索引付けされていないフィールドにフィルタをかける(大規模な表がある場合はデータベース層にアクセスする)か、2)任意のIQueryableを実行するかデータベース(GroupBy、Joinなど)に大きな負荷をかける操作。

2を防ぐために、私は通常、ユーザがIEnumerable<Product> LoadProducts(Predicate<Product> filter)メソッドを通してオブジェクトを読み込むことを許可してから、IQueryableのWhereに変換します。これは他のIQueryableメソッドを隠していますが、フィルタリングの目的にのみ完全な柔軟性を提供します。

+0

あなたの答えをありがとう!遅延実行を許可するために、リポジトリから常にIQueryableを返します。私のサービス層は常にIEnumerableを返します。述語を使って、あなたのテクニクを例に説明してもよろしいですか? – CiccioMiami

+1

次のメソッドがあるとします。 'IEnumerable LoadProducts(Expression > filter)'、それを 'return myQueryable 'として実装できます。ここでは(フィルタ) 'とラムダ式で呼び出すことができます:' IEnumerable results = LoadProducts(p => p.Color == Colors.Red) ' –

関連する問題