54

動的フィルターを作成する必要があり、エンティティを引き続き使用したいと考えていました。このため、albahari の PredicateBuilder を使用したいと思いました。

次のコードを作成しました。

var invoerDatums = PredicateBuilder.True<OnderzoeksVragen>();
var inner = PredicateBuilder.False<OnderzoeksVragen>();

foreach (var filter in set.RapportInvoerFilter.ToList())
{
    if(filter.IsDate)
    {
        var date = DateTime.Parse(filter.Waarde);
        invoerDatums = invoerDatums.Or(o => o.Van >= date && o.Tot <= date);
    }
    else
    {
        string temp = filter.Waarde;
        inner = inner.Or(o => o.OnderzoekType == temp);
    }
}

invoerDatums = invoerDatums.And(inner);
var onderzoeksVragen = entities.OnderzoeksVragen
                               .AsExpandable()
                               .Where(invoerDatums)
                               .ToList();

コードを実行すると、日付フィルターではないフィルターが 1 つしかありませんでした。したがって、内側の述語のみが満たされました。述語が実行されると、次のエラーが発生しました。

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

答えを探しているときに、次のページを見つけました。しかし、これはすでに LINQKit に実装されています。

他の誰かがこのエラーを経験し、それを解決する方法を知っていますか?

4

2 に答える 2

122

私は同じエラーに出くわしました.PredicateBuilderで作成された述語がPredicateBuilderで作成された他の述語で構成されていたときに問題が発生したようです

たとえば、(A OR B) AND (X OR Y) の場合、1 つのビルダーが A OR B を作成し、1 つが X OR Y を作成し、3 つ目がそれらを AND します。

複数のレベルが導入されたとき、同じエラーが発生しました。

助けを見つけることはできませんでしたが、試行錯誤の末、物事を機能させることができました。述語を呼び出すたびに、Expand 拡張メソッドを使用しました。

簡単にするために省略されたコードの一部を次に示します。

public static IQueryable<Submission> AddOptionFilter(
    this IQueryable<Submission> query, 
    IEnumerable<IGrouping<int, int>> options)
{
    var predicate = options.Aggregate(
        PredicateBuilder.False<Submission>(),
        (accumulator, optionIds) => accumulator.Or(ConstructOptionMatchPredicate(optionIds).Expand()));
        query = query.Where(predicate.Expand());            
    return query;
}

Query は既に AsExpandable が呼び出されている IQueryable であり、ConstructOptionNotMatchPredicate は Expression を返します。

エラーを乗り越えると、実行時にエンティティ フレームワークに対して複雑なフィルターを構築することができました。

編集:

人々はまだこれにコメントして投票しているので、私はそれがまだ有用であると考えているので、別の修正を共有しています. 基本的に、私は LinqKit の使用をやめました。それは、同じ API を持つが Expand 呼び出しを必要としないこのユニバーサル述語ビルダーを支持する述語ビルダーであり、チェックする価値があります。

于 2010-06-02T11:39:36.720 に答える
44

このエラーが発生し、Mant101 の説明で答えが得られましたが、問題の原因となるより簡単な例を探しているかもしれません。

// This predicate is the 1st predicate builder
var predicate = PredicateBuilder.True<Widget>();

// and I am adding more predicates to it (all no problem here)
predicate = predicate.And(c => c.ColumnA == 1);
predicate = predicate.And(c => c.ColumnB > 32);
predicate = predicate.And(c => c.ColumnC == 73);

// Now I want to add another "AND" predicate which actually comprises 
// of a whole list of sub-"OR" predicates
if(keywords.Length > 0)
{
    // NOTICE: Here I am starting off a brand new 2nd predicate builder....
    // (I'm not "AND"ing it to the existing one (yet))
    var subpredicate = PredicateBuilder.False<Widget>();

    foreach(string s in keywords)
    {
        string t = s;  // s is part of enumerable so need to make a copy of it
        subpredicate = subpredicate.Or(c => c.Name.Contains(t));
    }

    // This is the "gotcha" bit... ANDing the independent
    // sub-predicate to the 1st one....

    // If done like this, you will FAIL!
//  predicate = predicate.And(subpredicate); // FAIL at runtime!

    // To correct it, you must do this...
    predicate = predicate.And(subpredicate.Expand());  // OK at runtime!
}

お役に立てれば!:-)

于 2012-07-04T22:39:03.060 に答える