使用!DateTime.HasValue创建表达式树

时间:2017-05-24 22:02:09

标签: c# .net datetime

我有一个非常大的表达式树构建器,它已经构建并定期添加,因为需要新的功能。它一直适用于所有类型,包括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;
}

1 个答案:

答案 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;
}