我有一个非常大的表达式树构建器,它已经构建并定期添加,因为需要新的功能。它一直适用于所有类型,包括Nullable<>类型。我的几个Nullable<>类型是DateTime,因为我的数据库中的那些列允许空值。
现在,我需要调整方法,以便能够根据具有任何值的DateTime进行过滤。在SQL术语中:
WHERE date_Column IS NOT NULL
以LINQ术语:
.Where(s => !s.date_column.HasValue)
对于我的生活,我无法弄清楚如何将它添加到我的表达式树中。我可以将任何运算符添加到我喜欢的MyFilter类中,因此如果新案例有帮助,那就没问题了。
以下是为了便于阅读而将建筑物缩减为DateTime部分。
public class MyFilter
{
public string FieldName { get; set; }
public string FieldValue { get; set; }
public string Operator { get; set; }
}
private Expression<Func<MyDTO, bool>> CreateLambda(MyFilter myFilter)
{
ParameterExpression parameter = Expression.Parameter(typeof(MyDTO), "m");
Expression property = Expression.Property(parameter, myFilter.FieldName);
Expression target = null;
Expression exp = null;
PropertyInfo pi = null;
MethodInfo mi = null;
var switchType = property.Type.ToString();
switch (switchType)
{
case "System.DateTime":
target = (myFilter.FieldValue == "null") ?
Expression.Constant(null, property.Type) :
Expression.Constant(Convert.ToDateTime(myFilter.FieldValue));
switch (myFilter.Operator)
{
case "eq":
exp = Expression.Equal(property, Expression.Convert(target, property.Type));
break;
case "ne":
exp = Expression.NotEqual(property, Expression.Convert(target, property.Type));
break;
case "ge":
exp = Expression.GreaterThanOrEqual(property, Expression.Convert(target, property.Type));
break;
case "gt":
exp = Expression.GreaterThan(property, Expression.Convert(target, property.Type));
break;
case "le":
exp = Expression.LessThanOrEqual(property, Expression.Convert(target, property.Type));
break;
case "lt":
exp = Expression.LessThan(property, Expression.Convert(target, property.Type));
break;
}
break;
}
Expression<Func<MyDTO, bool>> lambda = Expression.Lambda<Func<MyDTO, bool>>(exp, parameter);
return lambda;
}
答案 0 :(得分:0)
Filip Cordas是正确的,他的两个陈述产生了同样正确的结果。我不知道为什么Expression.NotEquals
昨天没有为我工作,但上面的代码确实有效。
然而,由于我的问题是关于如何使用Nullable的HasValue属性,我非常赞赏Filip的第二个答案。而且,现在我已经看到它了,我自己无法得到它是令人羞愧的。
我在我的环境中使用HasValue实现的代码如下所示:
public class MyFilter
{
public string FieldName { get; set; }
public string FieldValue { get; set; }
public string Operator { get; set; }
}
private Expression<Func<MyDTO, bool>> CreateLambda(MyFilter myFilter)
{
ParameterExpression parameter = Expression.Parameter(typeof(MyDTO), "m");
Expression property = Expression.Property(parameter, myFilter.FieldName);
Expression target = null;
Expression exp = null;
PropertyInfo pi = null;
MethodInfo mi = null;
var switchType = property.Type.ToString();
switch (switchType)
{
case "System.DateTime":
target = (myFilter.FieldValue == "null") ?
Expression.Constant(null, property.Type) :
Expression.Constant(Convert.ToDateTime(myFilter.FieldValue));
switch (myFilter.Operator)
{
case "eq":
exp = Expression.Equal(property, Expression.Convert(target, property.Type));
break;
case "ne":
if (myFilter.FieldValue == "null")
{
exp = Expression.Property(property, "HasValue");
}
else
{
exp = Expression.NotEqual(property, Expression.Convert(target, property.Type));
}
break;
case "ge":
exp = Expression.GreaterThanOrEqual(property, Expression.Convert(target, property.Type));
break;
case "gt":
exp = Expression.GreaterThan(property, Expression.Convert(target, property.Type));
break;
case "le":
exp = Expression.LessThanOrEqual(property, Expression.Convert(target, property.Type));
break;
case "lt":
exp = Expression.LessThan(property, Expression.Convert(target, property.Type));
break;
}
break;
}
Expression<Func<MyDTO, bool>> lambda = Expression.Lambda<Func<MyDTO, bool>>(exp, parameter);
return lambda;
}