2017-05-24 130 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

很高興能幫到你 –