views:

249

answers:

2

I needed to build a dynamic filter and I wanted to keep using entities. Because of this reason I wanted to use the PredicateBuilder from albahari.

I created the following code:

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();

When I ran the code there was only 1 filter which wasn't a date filter. So only the inner predicate was filled. When the predicate was executed I got the following error.

The parameter 'f' was not bound in the specified LINQ to Entities query expression.

While searching for an answer I found the following page. But this is already implemented in the LINQKit.

Does anyone else experienced this error and know how to solve it?

A: 

Does the following help?

http://social.msdn.microsoft.com/Forums/en/adodotnetentityframework/thread/8c2b0b1c-01bb-4de2-af46-0b4ea866cf8f

Joe Albahari
No, I already found this page. It leads to the page I linked. Thanks though
Neothor
+1  A: 

I ran across the same error, the issue seemed to be when I had predicates made with PredicateBuilder that were in turn made up of other predicates made with PredicateBuilder

e.g. (A OR B) AND (X OR Y) where one builder creates A OR B, one creates X OR Y and a third ANDs them together.

With just one level of predicates AsExpandable worked fine, when more than one level was introduced I got the same error.

I wasn't able to find any help but through some trial and error I was able to get things to work. Every time I called a predicate I followed it with the Expand extension method.

Here is a bit of the code, cut down for simplicity:

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 is an IQueryable which has already had AsExpandable called, ConstructOptionNotMatchPredicate returns an Expression.

Once we got past the error we were certainly able to build up complicated filters at runtime against the entity framework.

Mant101
It seems to work by adding .Expand() to inner and invoerDatums. Thanks
Neothor