4

Using EF 6. Can someone tell me what am I doing wrong?

public List<SearchResult> SearchDocuments(List<SearchCriteria> searchCriterias)
{
    List<SearchResult> results = new List<SearchResult>();
    var fieldSettings = LoadCoordinateSystemFieldSettings(searchCriterias);
    using (var context = CreateContext())
    {
        var tractsQuery = PredicateBuilder.False<v_UploadByTract_ActiveUploads>();
        foreach (var searchCriteria in searchCriterias)
        {
            var queryBuilder = PredicateBuilder.True<v_UploadByTract_ActiveUploads>();

            // tractsQuery
            if (searchCriteria.StateAPI.HasValue)
                queryBuilder = queryBuilder.And(a => a.StateAPI == searchCriteria.StateAPI.Value);
            if (searchCriteria.CountyAPI.HasValue)
                queryBuilder = queryBuilder.And(a => a.CountyAPI == searchCriteria.CountyAPI.Value);

            // ...
            // ... many more similar IF-ANDs
            // ...

            tractsQuery = tractsQuery.Or(queryBuilder);
        }

        var searchQuery = context.v_UploadByTract_ActiveUploads.AsExpandable().Where(tractsQuery).ToList();
        //.Select(a => SearchResult.Create(a));
        //results.AddRange(searchQuery.ToList());
    }

    return results;
}

public static class PredicateBuilder
{
    public static Expression<Func<T, bool>> True<T>() { return f => true; }
    public static Expression<Func<T, bool>> False<T>() { return f => false; }

    public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1,
                                                        Expression<Func<T, bool>> expr2)
    {
        var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
        return Expression.Lambda<Func<T, bool>>
              (Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters);
    }

    public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1,
                                                         Expression<Func<T, bool>> expr2)
    {
        var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
        return Expression.Lambda<Func<T, bool>>
              (Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters);
    }
}
quetzalcoatl
  • 32,194
  • 8
  • 68
  • 107
Deepak
  • 126
  • 1
  • 11
  • I've reviewed and trimmed your code example a little. Since like 70% of this code was the same repeated IF-THEN-AND blocks, they really could not add nothing new to the problem. Also, strangely, I don't see what could be the problem. Since you have `expr2.Invoke`, the parameter bindings are in place.. maybe EF6's expression analyzer has some deficiencies.. or maybe I didnt notice something – quetzalcoatl Nov 13 '14 at 12:59
  • @Daniel A. White, That's not the same question. – haim770 Nov 13 '14 at 13:03
  • 1
    @DanielAWhite: the fact that the title is similar does not make this question a duplicate. Sure, there could be some text added (especially in the OTHER question!), but the problem here is different than in the linked question. Here is `Expression.Invoke` used that should provide the mapping, while in the 'duplicate' problem was with general misunderstanding the 'parameters' – quetzalcoatl Nov 13 '14 at 13:03
  • 1
    Uh.. I see I didnt manage to find it on time.. I think I've found the actual duplicate: http://stackoverflow.com/questions/2947820/c-sharp-predicatebuilder-entities-the-parameter-f-was-not-bound-in-the-specif?rq=1 - so please review that solution, especially the second one that uses `Expand()`. Also, it'd be helpful if someone changed the dup-link to this.. – quetzalcoatl Nov 13 '14 at 13:38

2 Answers2

0

quetzalcoatl thanks for the answer. The other post did it. From else where I had come across AsExpandable() and overlooked this one thinking it's talking about the same. After reading your post and re-reading the discussion, this worked. Since your post shows up as "comment", I am unable to mark that as the answer. Any suggestions on how to consolidate those nasty IFs.

C# PredicateBuilder Entities: The parameter 'f' was not bound in the specified LINQ to Entities query expression

Community
  • 1
  • 1
Deepak
  • 126
  • 1
  • 11
0

For anyone else googling into here, my solution was to Visit a modified expression before returning it into the expression tree. This bound the lambda parameter.

user326608
  • 2,210
  • 1
  • 26
  • 33
  • can you share an example on what you mean by `Visit`? – Sagiv b.g Jul 29 '18 at 07:03
  • https://msdn.microsoft.com/en-us/library/dd323929(v=vs.110).aspx - see example here: http://pelebyte.net/blog/2011/05/13/doing-simple-things-with-expressionvisitor/ – user326608 Aug 07 '18 at 02:58