c# - 使用 Linq 表达式返回默认 DateTime

标签 c# linq datetime expression

我正在尝试为我正在使用基于这篇文章的表达式树的规则引擎构建一些附加功能 - How to implement a rule engine?

我的规则之一是,如果发现该属性类型是 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”时,在这种情况下会抛出越界异常,因为它试图减去 180 DateTime.Min 的分钟数。

我试图通过使用 Expression.IfThenElse 来解决这个问题,这样如果 DateTime 属性等于 DateTime.Min,则不进行计算而只对 DateTime.Min 求值。

我更新后的代码如下所示:

 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 进行比较。我尝试了几种变体,但总是得到相同的异常。

谁能告诉我如何构造一个能够执行此逻辑的表达式?

最佳答案

Expression.IfThenElse 等效于 C# - 好吧,if 语句,而您需要的是等效于 C# ?: 的表达式(又名 条件)运算符,即 ConditionalExpressionExpression.Condition 制作方法。

很快,替换

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

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

你就完成了。

关于c# - 使用 Linq 表达式返回默认 DateTime,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38489602/

相关文章:

c# - 如何将进程输出重定向到 System.String

c# - Xamarin.Forms:在 ListView 中添加标签?

c# - 获取 LINQ 投影中的属性列表

vb.net - 在 VB 中编写我自己的 IsDate 函数

c# - .NET 进程外服务器的#import 问题

c# - 需要一个模式来为每个实例方法模式调用 Verify 方法

c# - 在 ORM 中将 lambda 表达式转换为 SQL?

c# - Linq where element.equals 一个数组

java - JodaTime IllegalArgumentException 格式无效 "yyyy-MM-dd hh:mm:ss"

python - 将 n 个工作日添加到给定日期,忽略 python 中的假期和周末