2015-04-24 126 views
0

我有一個包含DateTime類型的多列的表。我要動態地生成以下Expression如何動態生成SqlFunctions.DateDiff

filter= p => SqlFunctions.DateDiff("day", p.CreatedDate.Date, date) > 0; 

當我知道列的名稱和運營商(運營商可以爲=>=<=等..。

請記住我想忽略時間部分形式Datetime

回答

1

好吧,如果你使用SqlFunctions.DateDiff,那一定意味着你在LINQ合作實體。所以我不認爲你可以使用p.CreatedDate.Date,但你必須使用EntityFunctions.TruncateTime(p.CreatedDate)

無論如何。

你可以去這樣的事情(只是一般的想法,這當然應該改進)。

假設p類型是Employee

public static class ExpressionHelper { 
    //we create a Dictionary to manage the comparison operators, 
    //which will probably make things easier when calling the main method. 
    public static Dictionary<string, ExpressionType> Comparators = new Dictionary<string, ExpressionType> 
     { 
      {">", ExpressionType.GreaterThan}, 
      {">=", ExpressionType.GreaterThanOrEqual}, 
      {"<", ExpressionType.LessThan}, 
      {"<=", ExpressionType.LessThanOrEqual} 
     }; 

    public static Expression<Func<Employee, bool>> BuildFilterExpression(string datePart, DateTime date, string comparisonOperator) 
     { 
      var parameter = Expression.Parameter(typeof (Employee), "p"); 
      Expression member = parameter; 
      //the property is a string here, it could be passed as parameter 
      //or managed another way 
      member = Expression.Property(member, "CreatedDate"); 
      //let's find the dateDiffMethod 
      var dateDiffMethod = typeof (SqlFunctions).GetMethod("DateDiff", new[] {typeof (string), typeof (DateTime), typeof(DateTime)}); 
      //same for TruncateTime method 
      var truncateTimeMethod = typeof (EntityFunctions).GetMethod("TruncateTime", new[] {typeof (DateTime)}); 
      //first call truncateTime method (to keep only "Date" part) 
      var truncateExpression = Expression.Call(truncateTimeMethod, member); 
      //call dateDiff method on that 
      var dateDiffExpression = Expression.Call(dateDiffMethod, Expression.Constant(datePart), truncateExpression, Expression.Constant(date, typeof(DateTime?))); 
      //find the comparison operator 
      var comparator = Comparators[comparisonOperator]; 
      //apply the comparison 
      var finalExpression = Expression.MakeBinary(comparator, dateDiffExpression, Expression.Constant(0, typeof(int?))); 
      return Expression.Lambda<Func<Employee, bool>>(finalExpression, new []{parameter}); 
     } 
} 

使用,與您的代碼將是類似的東西

filter = ExpressionHelper.BuildFilterExpression("day", date, ">") 
+0

感謝。它似乎只適用於'DateTime?'的列,因爲'DateDiff'函數不接受'DateTime'作爲參數。任何想法如何才能將它用於具有'DateTime'類型的列? – roroinpho21

+0

我解決了它,我添加了'Expression.Convert'來將'DateTime'轉換爲'DateTime?' – roroinpho21

+0

@ roroinpho21好。順便說一下,我看到你永遠不會接受答案。這將是一件好事,因爲它表明你已經找到了所需的答案,並且顯示問題已關閉,以供其他用戶使用。 –