7

アプリケーション全体のさまざまなクエリで発生する特定の基準セットは、徐々に複雑になってきています。このコードの重複を避けるために、条件をExpressionとして返すメソッドにこれらの条件を分割し、必要に応じて適用できるようにします。

public Expression<Func<Invoice, bool>> GetComplexPredicate()
{
    // complex predicate is returned as an Expression:
    return c => ...
}

そのように再利用されます:

var result = repository.Invoice.Where(GetComplexPredicate())

ただし、c.Invoiceは単なるICollectionであるため、以下のステートメントはコンパイルされません。

var result = repository.Customer
    .Where(c => c.Country == "US" && c.Invoice.Any(GetComplexPredicate()))

このような表現をどのように使用することは可能なのでしょうか?

4

1 に答える 1

7

この質問には 2 つの部分があります。

L2E クエリ内のナビゲーション プロパティで述語式を使用するにはどうすればよいですか?

L2E では、クエリ内でAsQueryable拡張メソッドを使用できます。これは、 ICollectionIQueryableに変換し、述語式を適用できることを意味します。ここまでは順調ですね。ただし、L2E は GetComplexPredicate メソッドからの事前定義された式をどう処理するかを認識できないため、コンパイルは可能ですが、それでも実行されません。これにより、次のことがわかります。

複数の個別の述語式を 1 つに結合するにはどうすればよいですか?

非常に便利なLINQKitは、 PredicateBuilderを使用して、複数の述語を 1 つの式に簡単に結合できます。LINQKitのExpandメソッドと前述のAsQueryableを使用すると、コンパイルと実行の両方を美しく行うステートメントに最終的にたどり着くことができます。

// build the entire predicate beforehand (PredicateBuilder + AsQueryable):
var complexPredicate = GetComplexPredicate();
var condition = PredicateBuilder.True<Customer>()
    .And(c => c.Country == "US")
    .And(c => c.Invoice.AsQueryable().Any(complexPredicate));

// apply criteria to query (using Expand):
var result = repository.Customer.Where(condition.Expand()).ToList();
于 2013-06-26T17:07:16.070 に答える