如何在entity framework中查找具有指定日期范围列表的日期?

我有一个IEnumerable我创建的类包含日期范围。 那个class看起来像这样:

public class Range where T: struct { public T Start { get; set; } public T End { get; set; } } 

我想查找我的集合中的所有记录,其中日期列落在指定日期范围的任何一个范围内。 这是我的尝试:

 deals = deals.Where( deal => criteria.DateRanges.Any( dt => deal.CloseDate >= dt.Start && deal.CloseDate < dt.End.Value.AddDays(1))); 

这会抛出我假设的错误,因为EF不知道如何将criteria.DateRanges.Any()转换为SQL。 那你怎么写这个来查找与任何日期范围相匹配的日期?

您可以使用LinqKit :

 var expr = PredicateBuilder.False(); foreach(var range in criteria.DateRanges) expr = expr.Or(d => dt.CloseDate >= range.Start && dt.CloseDate < range.End); deals = deals.AsExpandable().Where(expr); 

另一个选择是使用表达式树,但这对你正在尝试做的事情似乎有点过分。

同意@stuartd,如果有一些范围条件,你可以构建自己的表达式And为每个范围创建一个And表达式,并在几个Ors中将它们组合在一起。 您可以创建一个这样的静态generics方法:

 public static Expression> RangeExpression(string property, IEnumerable> criterias ) { Expression result = null; ParameterExpression parameterExpression = Expression.Parameter(typeof(T), "o"); foreach (var item in criterias) { var value1 = item.Start.Date; var value2 = item.End.Date.AddDays(1); MemberExpression memberExpression1 = Expression.PropertyOrField(parameterExpression, property); MemberExpression memberExpression2 = Expression.PropertyOrField(parameterExpression, property); ConstantExpression valueExpression1 = Expression.Constant(value1, typeof(DateTime)); ConstantExpression valueExpression2 = Expression.Constant(value2, typeof(DateTime)); BinaryExpression binaryExpression1 = Expression.GreaterThanOrEqual(memberExpression1, valueExpression1); BinaryExpression binaryExpression2 = Expression.LessThan(memberExpression2, valueExpression2); var ret1 = Expression.Lambda>(binaryExpression1, parameterExpression); var ret2 = Expression.Lambda>(binaryExpression2, parameterExpression); Expression and = Expression.And(ret1, ret2); result = result!=null?Expression.OrElse(result, and):and; } return Expression.Lambda < Func>(result, parameterExpression); } 

稍后在您的代码中,您可以执行以下操作:

 var rangeExp=RangeExpression("CloseDate",criteria.DateRanges); deals = deals.Where(rangeExp);