5

ループを使用して動的に構築するのに苦労しているカスタム フィルターにドキュメントを渡すことで、ドキュメントのリストをフィルター処理する必要があります。foreach

var mainPredicate = PredicateBuilder.True<Document>();

// mainPredicate is combined to other filters successfully here ...

var innerPredicate = PredicateBuilder.False<Document>();
foreach (var period in periods)
{
    var p = period;
    Expression<Func<Document, bool>> inPeriod =
        d => d.Date >= p.DateFrom && d.Date <= p.DateTo;

    innerPredicate = innerPredicate.Or(d => inPeriod.Invoke(d));
}

mainPredicate = mainPredicate.And(innerPredicate);

この最後の行:

documents = this.ObjectSet.AsExpandable().Where(mainPredicate).ToList();

この例外をスローします:

パラメーター 'd' は、指定された LINQ to Entities クエリ式でバインドされていませんでした。

この例外が発生する理由を知っている人はいますか? InPeriod メソッドに渡す 'd' パラメータがどこで失われるのかわかりません。これが機能するために何が欠けているのかわかりません。私のコードは、完全に機能する他の多くの例と同じです。式の呼び出しと、それが舞台裏でどのように機能するかについての追加の理論的な情報は大歓迎です。

4

3 に答える 3

1

最後に、複数の述語をメインの式ツリーに結合しないようにする方法を見つけました。

各述語が異なるフィルターを表し、最終的な組み合わせフィルターを一連の尊重する必要がある条件にしたい場合、最後の述語がtrueを返すには、各述語が true を返す必要があると言えます。

それが機能するには、述語を と組み合わせる必要がありANDます。したがって、結果の SQL クエリは次のようになります。

predicate1 AND predicate2 AND predicate3...

これらの述語を組み合わせるより良い方法は、次のように、クエリ演算子を最終的なクエリにANDチェーンすることです。Where

var documents = this.ObjectSet.AsExpandable()
    .Where(mainPredicate)
    .Where(otherPredicate)
    .Where(yetAnotherPredicate)
    .ToList();

結果の SQL クエリは、これらの各述語を で結合しANDます。それがまさに私がやりたかったことです。

自分で式ツリーをハッキングするよりも簡単です。

于 2013-05-13T12:53:38.400 に答える