[英]Creating an Expression Tree with !DateTime.HasValue
I have a very large expression tree builder that has been built and added to regularly as new functionality was needed. 我有一个非常大的表达式树生成器,可以根据需要添加并定期添加新功能。 It has been working perfectly for all types including Nullable<> types. 它对所有类型(包括Nullable <>类型)都运行良好。 Several of my Nullable<> types are DateTime as those columns in my database allow nulls. 我的Nullable <>类型中有几种类型是DateTime,因为数据库中的那些列允许为空。
Now, I need to adjust the method to be able to filter based on a DateTime having ANY value. 现在,我需要调整方法以能够基于具有ANY值的DateTime进行过滤。 In SQL terms: 用SQL术语:
WHERE date_Column IS NOT NULL
In LINQ terms: 用LINQ术语:
.Where(s => !s.date_column.HasValue)
For the life of me, I cannot figure out how to add this to my expression tree. 对于我的一生,我无法弄清楚如何将其添加到表达式树中。 I can add any operator to the MyFilter class that I like, so if a new case will help, that is no problem. 我可以将任何运算符添加到我喜欢的MyFilter类中,因此,如果有新的案例有用,那就没问题了。
Below is the builder cut down to just the DateTime portion for readability. 下面是构建器,出于可读性考虑,它仅缩减到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;
}
Filip Cordas was correct and both his statements produce the same correct result. 菲利普·科尔达斯(Filip Cordas)是正确的,他的两句话都得出了正确的结果。 I have no idea why Expression.NotEquals
was not working for me yesterday, but the code above does work as is. 我不知道为什么Expression.NotEquals
昨天对我不起作用,但是上面的代码仍然可以正常工作。
However, since my question was about how to use the HasValue property of a Nullable, I appreciated Filip's second answer very much. 但是,由于我的问题是关于如何使用Nullable的HasValue属性的,所以我非常感谢Filip的第二个答案。 Also, now that I see it, it is humbling that I could not get it myself. 另外,现在我看到了,我自己也无法获得它,这令人感到沮丧。
The code I implemented to use the HasValue within my environment looks like the following: 我为在环境中使用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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.