2017-05-24 98 views
0

我有一个非常大的表达式树构建器,它已经被构建并定期添加,因为需要新的功能。它一直适用于所有类型,包括可空值<>类型。我的几个Nullable <>类型是DateTime,因为数据库中的那些列允许空值。用!DateTime.HasValue创建表达式树

现在,我需要调整方法以便能够根据具有ANY值的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

您正在尝试null'转换''要和DateTime'不''日期时间?对于所有'?'类型,名称都是Nullable1您正在使用EF作为查询权限?你的财产应该是'DateTime?。' –

+0

我认为我们需要更多的帮助或类型来理解。 '参数'来自哪里/哪里?什么是“财产”?为什么没有'myFilter.FieldValue' ==“null”和'myFilter.Operator'是“ne”的工作? – NetMage

+0

@FilipCordas C#中的所有对象都接受null作为可能的值。 'DateTime'也不例外。 – NetMage

回答

0

菲利普科达斯是正确的,他的言论都产生了相同的正确结果。我不知道为什么Expression.NotEquals昨天不适合我,但上面的代码确实按原样工作。

但是,由于我的问题是关于如何使用Nullable的HasValue属性,我非常赞赏Filip的第二个答案。而且,现在我看到它了,我自己无法得到它是令人h嘘的。

我实现用我的环境中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; 
} 
+0

很高兴能帮到你 –