如何动态生成SqlFunctions.DateDiff

时间:2015-04-24 12:58:12

标签: c# linq

我有一个包含多个DateTime类型列的表。我想动态生成以下Expression

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

当我知道列的名称和运算符时(运算符可以是=>=<=等等。

请注意,我想忽略时间部分表单Datetime

1 个答案:

答案 0 :(得分:2)

好吧,如果你使用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, ">")