0

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.

rdethurens
  • 283
  • 1
  • 4
  • 13
  • 1
    It is quite improbable `FilterDate` will work. Remember that the expression you write in the `Where` will be translated to SQL and sent to the SQL Server (or other DB)... The SQL Server doesn't know of `FilterDate` – xanatos May 24 '18 at 09:42
  • You could do something with expression composition (see [here](https://stackoverflow.com/questions/457316/combining-two-expressions-expressionfunct-bool) for example, but it is a pain. – xanatos May 24 '18 at 09:45
  • @xantos I strongly recommend posting that as an answer as it answers all of the questions asked by OP. – mrogal.ski May 24 '18 at 09:51

1 Answers1

2

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.

xanatos
  • 109,618
  • 12
  • 197
  • 280
  • Thanks for all, i understand. I think you are write about it. maybe it will be less maintenable in my case. Thanks for your expertise – rdethurens May 24 '18 at 12:24