【发布时间】:2016-11-23 13:24:39
【问题描述】:
我正在使用 LINQ->WCF 数据服务->EF,它支持 LINQ 的一个子集,但有一些注意事项。一旦学习了各种技巧和解决方法,我对此没有任何问题,但我想制作一个可重用的表达式生成器,仅比较 DateTime 的 Date 部分。
对于常规 EF,您可以使用 EntityFunctions.TruncateTime (EFDbFunctions.TruncateTime (EF6+),但这不适用于数据服务。
到目前为止,我的解决方案是反复构建这种混乱的 where 子句:
.Where(x => x.DateProperty.Year == DateToCompare.Year &&
x.DateProperty.Month == DateToCompare.Month &&
x.DateProperty.Day == DateToCompare.Day);
不得不重复写这很讨厌(但它有效),所以我试图创建类似的东西:
.WhereDate(x => x.DateProperty, DateToCompare);
任何类似的东西都可以,只是简短、甜美和易读 - 我讨厌重复不必要的代码。
结构不是问题,我知道我需要一些包含IQueryable<T>、Func<T, DateTime>(或Expression<Func<T, DateTime>>)和DateTime 并返回IQueryable<T> 的东西。
public static IQueryable<T> WhereDate<T>(this IQueryable<T> data, Func<T, DateTime>> selector, DateTime date)
{
return data.Where(/*Something*/);
};
我遇到麻烦的地方是使用这个并构建一个可以放入 where 子句的表达式,而不会违反表达式树的限制。我不完全确定如何在不执行 .Where 的情况下获取现有查询并将我自己的 where 语句添加到表达式中,我认为这可能是这里的关键。我想我需要接收一个Expression<Func<T, DateTime>> 并构建一些东西来使用它来添加一个Expression<Func<T, bool>> to the tree and return it as anIQueryable`。
有人对此有一些经验,或者知道我应该阅读哪些文档吗?
这里最大的障碍是您无法将基于语句的 lambda 转换为表达式,并且您无法将不受支持的函数传递给数据服务或 EF。这使得所有幼稚的解决方案都变得不可能,据我所知,手动表达式操作。
【问题讨论】:
-
看看this link。
-
为什么不能在扩展方法中返回第一个 where 表达式?
-
@user2697817 因为 OP 希望它对任何实体都通用且有用
-
@DavidG 我不明白。该方法是通用的,适用于任何具有
DateTime属性的实体。我有一种感觉,我错过了一些明显的东西。 -
@user2697817 去尝试让它工作,你会明白为什么它更复杂!
标签: c# entity-framework linq wcf datetime