Factorise在linq到实体中的公共过滤器

时间:2018-05-24 09:40:42

标签: c# linq-to-entities predicate

我试图分解一些代码。我有很多自定义对象列表。所有这些都在他们自己的特定字段和其中一个日期上进行过滤。过滤日期很复杂,我想将其分解。这是一些代码示例:

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() ;

所以问题是如何声明FilterFunction来检查日期时间给定或如何更改我的where子句以使用自定义过滤器和常用过滤器?

提前致谢。

1 个答案:

答案 0 :(得分:2)

这是不太可能的FilterDate()将起作用。请记住,您在Where()子句中编写的表达式将被转换为SQL并发送到SQL Server(或其他数据库)... SQL Server不知道FilterDate()并且您将得到一个例外(由实体框架)。

可以创建一个返回FilterDate的{​​{1}}方法,例如

Expression<>

然后

// 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;
}

然后使用this

中的代码组合此表达式
Expression<Func<Customer, bool>> filterA = x => x.Country == "USA";
Expression<Func<Customer, bool>> filterB = FilterDate<Customer>(x => x.DateMeeting);
但请相信我,这是一种痛苦,收获甚微。它很复杂。可悲的是,表达树很难构成。