是的,由于各种原因,这不会让人高兴;
- 首先,LINQ 解释器可以直接处理——它需要帮助
- 其次,实现的属性返回与 相关的东西
this
,但实际上我们需要与 a ParameterExpression
(aka sh
)相关的东西
最简单的做法可能是添加一个扩展方法,让您可以方便地对此进行过滤,例如通过重写Expression
:
var filtered = source.WhereTransactionDate(when => when > DateTime.Now);
实施:
static class Utils
{
static readonly Expression<Func<Foo, DateTime>> tranDateTime =
x => x.TransactionDate.AddMinutes(SqlMethods.DateDiffMinute(
x.TransactionTime, new DateTime(1900, 1, 1)));
public static IQueryable<Foo> WhereTransactionDate(
this IQueryable<Foo> source,
Expression<Func<DateTime, bool>> predicate)
{
var visited = SwapVisitor.Swap(predicate.Body,
predicate.Parameters.Single(), tranDateTime.Body);
var lambda = Expression.Lambda<Func<Foo, bool>>(
visited, tranDateTime.Parameters);
return source.Where(lambda);
}
class SwapVisitor : ExpressionVisitor
{
public static Expression Swap(Expression source,
Expression from, Expression to)
{
return new SwapVisitor(from, to).Visit(source);
}
private SwapVisitor(Expression from, Expression to)
{
this.from = from;
this.to = to;
}
readonly Expression from, to;
public override Expression Visit(Expression node)
{
return node == from ? to : base.Visit(node);
}
}
}
这样做是合并两个表达式树,即
x => x.TransactionDate.AddMinutes(SqlMethods.DateDiffMinute(
x.TransactionTime, new DateTime(1900, 1, 1)))
和:
when => when > DateTime.Now
用第一个表达式中的主体替换所有when
内容(并使用第一个表达式中的参数),即创建
x => x.TransactionDate.AddMinutes(SqlMethods.DateDiffMinute(
x.TransactionTime, new DateTime(1900, 1, 1))) > DateTime.Now;