views:

169

answers:

1

I need to create and combine several expressions for child entity into one to use it on "Any" operator of a parent. Code now looks like this:

Expresion<Child, bool> startDateExpression;

if(String.IsNullOrEmpty(startDate)
     startDateExpression = t => true;
else
     startDateExpression = t => t.start_date >= startDate;

Expression<Child, bool> endDateExpression;

if(String.IsNullOrEmpty(endDate)
     endDateExpression = t => true;
else
     endDateExpression = t => t => t.end_date <= endDate;


....
ParameterExpression param = startDateExpression.Parameters[0];

Expression<Func<T, bool>> Combined = Expression.Lambda<Func<Child, bool>>( 
        Expression.AndAlso(startDateExpression.Body, endDateExpression.Body), param);

//but now I am trying to use combined expression on parent 
//this line fails just to give an idea on what I am trying to do:
//filter type is IQueryable<Parent>;
var filter = filter.Where(p =>p.Children.Any(Combined));

How can I do that? Is there better(more elegant way way of doing it? Maybe I should convert child expression into parent expression?

A: 

I'm not entirely sure why you are building expressions instead of using lambda functions. Have you tried the following?

var filter = filter.Where(p =>p.Children.Any(
   child => (String.IsNullOrEmpty(startDate) || child.start_date >= startDate) &&
            (String.IsNullOrEmpty(endDate) || child.end_date <= endDate)
));
Mark Byers
Thanks for reply. Because it's a dynamically created search criteria I have to do use expressions, see my update
Victor
@VictorS: I still don't see why you need to build the Expressions yourself. See if my updated answers solves your needs.
Mark Byers
This will probably fail since both child.start_date and child.end_date are DateTime? but I can use DateTime.MinimumValue instead
Victor
This gives me following compile error: "Delegate<System.Func<Parent, int, bool> does not take '1' arguments
Victor
Sorry, I think I have to give up on this one...
Mark Byers
Never give up:-) in fact I made it work like this: var filter = filter.Where(p =>p.Children.Any( child => (String.IsNullOrEmpty(startDate) || child.start_date >= DateTime.Parse(startDate)) Now I will just append some more conditions I left off for clarity
Victor
@VictorS: Glad to hear you got it working! :)
Mark Byers
Yeah, thanks so much, using expressions would be more elegant but never used them in "Any" operator.
Victor