【发布时间】:2019-07-17 17:51:26
【问题描述】:
我一直在尝试为 Linq 创建一个表达式树过滤器,它采用 2 个日期和一串可能的值 {“lessthan”、“equals”、“morethan”}。我希望将调用格式化为 Query.Where(CompareDates(x => x.left, right, "less than"));
我有代码:
public static IQueryable<TSource> CompareDates<TSource>(
this IQueryable<TSource> source,
Expression<Func<TSource, DateTime?>> left,
DateTime? right,
string equality)
{
if (right == null || string.IsNullOrWhiteSpace(equality))
return source;
var p = left.Parameters.Single();
Expression member = p;
Expression leftExpression = Expression.Property(member, "left");
Expression rightParameter = Expression.Constant(right, typeof(DateTime));
BinaryExpression BExpression = null;
switch (equality)
{
case "lessthan":
BExpression = Expression.LessThan(leftExpression, rightParameter);
break;
case "equal":
BExpression = Expression.Equal(leftExpression, rightParameter);
break;
case "morethan":
BExpression = Expression.GreaterThan(leftExpression, rightParameter);
break;
default:
throw new Exception(String.Format("Equality {0} not recognised.", equality));
}
return source.Where(Expression.Lambda<Func<TSource, bool>>(BExpression, p));
}
不幸的是,它在 SARRestAPI.Extensions 的 System.Linq.Expressions.Expression.Property(Expression expression, String propertyName) 中产生“System.ArgumentException:实例属性 'left' 未定义为类型 'Model' 的错误。 Expressions.CompareDates[TSource](IQueryable1 source, Expression1 src,提供的日期时间,字符串相等)"
有人知道为什么会这样吗?
【问题讨论】:
-
作为一个不相关的说明,我建议使用枚举而不是字符串作为相等参数
-
好的,所以
member是ParameterExpression中的ParameterExpression,即TSource。听起来TSource这里是Model,而你要求.left(通过Expression.Property(member, "left")) - 所以... 确实Model有一个.left财产?我们可以在这里看到Model吗?.left有可能是一个 field 吗? -
顺便说一句,IMO 你应该在这里合并树木......让我看看我能做什么