我有一个执行以下操作的Extension方法:
public static bool Between(this DateTime target, DateTime startDate, DateTime endDate)
{
return target >= startDate && target <= endDate;
}
我可以这样称呼它
if (expectedDate.Between(minDate, maxDate)) { do code }
我现在正试图在Linq / Lambda表达式中使用它,如
return list.Where(item => targetDate.Between(item.StartDate, item.EndDate));
OR if (!list.Any(pp => targetDate.Between(pp.StartDate, pp.EndDate)))
我在运行时遇到以下错误:
LINQ to Entities无法识别方法'布尔值 之间(System.DateTime,System.DateTime,System.DateTime)'方法, 并且此方法无法转换为商店表达式。
但这很好
if (!list.Any(item => targetDate >= item.StartDate && quoteDate.EventDate <=item.EndDate)))
我想要一个通用的方法来调用。我有什么选择?
答案 0 :(得分:4)
简单修改Brian的解决方案,不需要AsExpandable()
:
public static IQueryable<TSource> Between<TSource, TKey>(
this IQueryable<TSource> source, TKey key,
Expression<Func<TSource, TKey>> lowSelector,
Expression<Func<TSource, TKey>> highSelector)
where TKey : IComparable<TKey>
{
Expression low = lowSelector.Body;
Expression high = highSelector.Body;
Expression lowerBound = Expression.LessThanOrEqual(
low, Expression.Constant(key));
Expression upperBound = Expression.LessThanOrEqual(
Expression.Constant(key), high);
var lowLambda = Expression.Lambda<Func<TSource, bool>>(
lowerBound, lowSelector.Parameters);
var highLambda = Expression.Lambda<Func<TSource, bool>>(
upperBound, highSelector.Parameters);
return source.Where(lowLambda).Where(highLambda);
}
答案 1 :(得分:3)
由于您没有使用LINQ to Object,因此查询未被执行,而是转换为expression tree以转换为SQL。
LINQ to Entities在您实现它之后不知道如何将您编写的方法转换为SQL
我从未使用LINQ to Entities,但必须有一种方法来扩展表达式树构建器以使LINQ to Entities能够将您的方法转换为SQL,LINQ to NHibernate有办法这样做。
Here是如何将LINQ扩展为实体提供程序的示例。
答案 2 :(得分:1)
我使用了几种不同的方法。建立LINQ Between Operator之后,我创建了一个新方法
public static IQueryable<TSource> Between<TSource, TKey>(this IQueryable<TSource> source, TKey key, Expression<Func<TSource, TKey>> lowSelector, Expression<Func<TSource, TKey>> highSelector)
where TKey : IComparable<TKey>
{
Expression low = Expression.Invoke(lowSelector, lowSelector.Parameters.ToArray());
Expression high = Expression.Invoke(highSelector, highSelector.Parameters.ToArray());
Expression lowerBound = Expression.LessThanOrEqual(low, Expression.Constant(key));
Expression upperBound = Expression.LessThanOrEqual(Expression.Constant(key), high);
Expression<Func<TSource, bool>> lambda = Expression.Lambda<Func<TSource, bool>>(lowerBound, lowSelector.Parameters);
Expression<Func<TSource, bool>> lambda2 = Expression.Lambda<Func<TSource, bool>>(upperBound, highSelector.Parameters);
return source.AsExpandable().Where(lambda).Where(lambda2);
}
除非我使用AsExpandable或ToList(),否则这不起作用。
AsExpandable()来自LinkKit
ToList()强制它从Linq到实体进入Linq To Objects,但执行SQL。
感谢您的帮助和建议