I'm trying to factorise some code. i've got lots of list of custom object. All are filtered on thier own specific fields and on one of their date. the filter date is complex and i would like to factorise it. Here is some code exemple :
var usaCustomer = Context.Customer.Where(x => x.Country == "USA" && FilterDate(x.DateMeeting)).ToList() ;
var happySeeder = Context.Seeder.Where(x => x.Feel == "Good" && FilterDate(x.LastConnection)).ToList() ;
So the question is how can i declare the FilterFunction to make some check on the datetime Given or how can i change my where clause to have custom filter and common filter ?
Thanks in advance.
It is quite improbable FilterDate()
will work. Remember that the expression you write in the Where()
clause will be translated to SQL and sent to the SQL Server (or other DB)... The SQL Server doesn't know of FilterDate()
and you'll get an exception (by the Entity Framework).
It is possible to create a FilterDate
method that returns an Expression<>
, like
// Filter only for dates >= 1 jan 2000
public static Expression<Func<TSource, bool>> FilterDate<TSource>(Expression<Func<TSource, DateTime>> exp)
{
var body = exp.Body;
var date = new DateTime(2000, 1, 1);
// exp >= 1 jan 2000
var body2 = Expression.GreaterThanOrEqual(exp.Body, Expression.Constant(date));
var lambda = Expression.Lambda<Func<TSource, bool>>(body2, exp.Parameters);
return lambda;
}
and then
Expression<Func<Customer, bool>> filterA = x => x.Country == "USA";
Expression<Func<Customer, bool>> filterB = FilterDate<Customer>(x => x.DateMeeting);
and then compose this expression for example by using code from this,
var filterC = filterA.And(filterb);
var usaCustomer = Context.Customer.Where(filterC);
but trust me, it is a pain with little gain. And it is complex. Sadly expression trees are very difficult to compose.