Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use System.Linq.Expressions.Expression to filter based on children?

I have a filter that I use across many methods:

Expression<Func<Child, bool>> filter = child => child.Status == 1;

(actually is more complex than that)

And I have to do the following

return db.Parents.Where(parent => parent.Status == 1 &&
                                  parent.Child.Status == 1);

where the condition is the same as in the filter above.

I want to reuse the filter in this method. But I don't know how. I tried

return db.Parents.Where(parent => parent.Status == 1 &&
                                  filter(parent.Child));

but an Expression can't be used as a method

like image 446
Jader Dias Avatar asked Apr 27 '12 19:04

Jader Dias


2 Answers

If you want to combine expressions and still be able to use linq-to-sql, you may want to have a look at LinqKit. It walks inside your expression and replaces all the function calls by their contents before the sql conversion.

This way you'll be able to use directly

return db.Parents
       .AsExpandable()
       .Where(parent => parent.Status == 1 && filter(parent.Child));
like image 64
McX Avatar answered Oct 01 '22 18:10

McX


You can try this:

var compiledFilter = filter.Compile();
foreach (var parent in db.Parents.Where(parent => parent.Status == 1))
    if (compiledFilter(parent.Child))
        yield return parent;

It requires you to pull all of the parents, but unlike @HugoRune's solution, it doesn't require a 1:1 relation of Parent:Child.

I don't think this will be useful for your situation because of the different types involved, but just in case, here is an example of how you can combine Expressions: How do I combine LINQ expressions into one?

Edit: I had previously suggested using Compile(), but that doesn't work over LINQ-to-SQL.

like image 39
Tim S. Avatar answered Oct 01 '22 19:10

Tim S.