Simplest way to create a dynamic search to be applied on IQueryable

admin

Administrator
Staff member
Consider the case of having a single table (called Car) with the following columns and the corresponding entity

Code:
string Make
string Model
string Owner

Now I want to create a search where the user can choose (by the use of checkboxes) which properties the search should be targetted to. If more than one is chosen, then it should be sufficient if the search string is found in at least one of them.

Moreover, if multiple search strings are given (separated by a space), the search should match only if every word is found (so for example, given search string "ter mist", a car with an owner "mister" would match).

After doing some research, I figured I'd create a list of
Code:
Expression<Func<Car, bool>>
for each of the chosen properties, add one for each word in the search string and then And all these together to create a single
Code:
Expression<Func<Car, bool>>
. Once I had these for all the chosen propeties, I would Or them together, to create the final filter. This, however, is where I am struggling.

In the end, the furthest I got was a NotSupportedException saying
Code:
The LINQ expression node type 'Invoke' is not supported in LINQ to Entities.

Here are the helper functions I have for doing the combining (found from <a href="http://social.msdn.microsoft.com/Fo.../thread/60a1f4c0-d4d9-4143-91aa-79d29dde7a7c/" rel="nofollow">http://social.msdn.microsoft.com/Fo.../thread/60a1f4c0-d4d9-4143-91aa-79d29dde7a7c/</a>):

Code:
public static Expression&lt;Func&lt;T, bool&gt;&gt; Or&lt;T&gt;(params Expression&lt;Func&lt;T, bool&gt;&gt;[] predicates)
    {
        if (predicates.Length == 1)
            return predicates[0];

        Expression&lt;Func&lt;T, bool&gt;&gt; result = predicates[0];
        for (int i = 1; i &lt; predicates.Length; i++)
        {
            result = OrTwo(result, predicates[i]);
        }

        return result;
    }
private static Expression&lt;Func&lt;T, bool&gt;&gt; OrTwo&lt;T&gt;(Expression&lt;Func&lt;T, Boolean&gt;&gt; expr1, Expression&lt;Func&lt;T, bool&gt;&gt; expr2)
    {
        var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast&lt;Expression&gt;());
        return (Expression.Lambda&lt;Func&lt;T, Boolean&gt;&gt;(Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters));
    }

This is all getting surprisingly confusing as well, so I'm starting to think that there must be an easier way to go about this. So, what would be the easiest way to solve this?

<hr>

<h1>Solution</h1>

After trying several things (LINQKit, <a href="http://www.albahari.com/nutshell/predicatebuilder.aspx" rel="nofollow">Albahari's PredicateBuilder</a>, fiddling with the expression trees myself), I finally ended up <a href="http://petemontgomery.wordpress.com/2011/02/10/a-universal-predicatebuilder/" rel="nofollow">here</a>. This universal version of the PredicateBuilder works without any other external dependencies, and is fully compatible with EF. It made solving the problem really trivial.