使用Linq表达式返回默认DateTime

本文关键字:默认 DateTime 返回 表达式 Linq 使用 | 更新日期: 2023-09-27 17:58:07

我正试图使用基于本文的表达式树为规则引擎构建一些附加功能-如何实现规则引擎?

我的规则之一是,如果发现属性类型为DateTime,则向该属性添加分钟数。例如,我可以有"DOB+60"或"DOB-180"。

我当前的代码适用于此:

 var expression = new string[] {"DOB", "+", "60"};
 var property = Expression.Property(param, expression[0]);
 var method = typeof(T).GetProperty(expression[0]).PropertyType.GetMethod("AddMinutes");
 /* If we have a AddMinutes method then assume type is of DateTime */
 if (method != null)
 {
     var tParam = method.GetParameters()[0].ParameterType;
     /* Calculate if we're adding or subtracting minutes */
     var convertedNo = expression[1] == "-" ? int.Parse(expression[2]) * -1 : int.Parse(expression[2]);
      var number = Expression.Constant(Convert.ChangeType(convertedNo, tParam));
      var exp = Expression.Call(property, method, number);
      /* Allows for left property < DOB.AddMinutes(60) */
      return Expression.MakeBinary(ExpressionType.LessThan, left, exp);
}

我遇到的问题是DOB属性可能设置为DateTime。Min,这样当我的表达式计算"DOB-180"时,在这种情况下,当它试图从DateTime中减去180分钟时,会抛出一个越界异常。最小

我试图通过使用表达式来绕过这个问题。IfThenElse,以便如果DateTime属性等于DateTime。Min,不要计算,只在DateTime上计算。最小

我更新的代码如下:

 var expression = new string[] {"DOB", "-", "180"};
 var property = Expression.Property(param, expression[0]);
 var method = typeof(T).GetProperty(expression[0]).PropertyType.GetMethod("AddMinutes");
 /* If we have a AddMinutes method then assume type is of DateTime */
 if (method != null)
 {
     var tParam = method.GetParameters()[0].ParameterType;
     /* Calculate if we're adding or subtracting minutes */
     var convertedNo = expression[1] == "-" ? int.Parse(expression[2]) * -1 : int.Parse(expression[2]);
      var number = Expression.Constant(Convert.ChangeType(convertedNo, tParam));
      var exp = Expression.Call(property, method, number);
      var minDate = Expression.Constant(Convert.ChangeType(DateTime.MinValue, typeof(DateTime)));
      var minDateCheck = Expression.MakeBinary(ExpressionType.Equal, property, minDate);
      var minDateExp = Expression.IfThenElse(minDateCheck, minDate, exp);
      /* To allow for left property < DOB == DateTime.Min ? DateTime.Min : DOB.AddMinutes(60) */
      return Expression.MakeBinary(ExpressionType.LessThan, left, minDateExp); // Exception thrown here
}   

不幸的是,这引发了异常-无法将DateTime与返回类型void进行比较。我试过几种变体,但总是得到相同的例外。

有人能向我展示我如何构建一个能够实现这一逻辑的表达式吗?

使用Linq表达式返回默认DateTime

Expression.IfThenElse等价于C#-好吧,if语句,而您需要的是等价于C#?的表达式:(又称条件)运算符,它是ConditionalExpression,由Expression.Condition方法生成。

不久,更换

 var minDateExp = Expression.IfThenElse(minDateCheck, minDate, exp);

带有

 var minDateExp = Expression.Condition(minDateCheck, minDate, exp);

你就完了。