在lambda表达式中声明文字日期

时间:2016-01-29 16:59:06

标签: c# .net lambda nunit

我目前正在开发一个简单的引擎,它可以从不同的类生成lamda表达式(使用反射和表达式工厂)。

我在尝试对我的引擎进行一些单元测试时遇到了问题。

我使用我的引擎生成一个lambda表达式,然后我将生成的lambda与一个"手工制作" lambda表达式。问题是当我在lambda表达式中使用DateTime时。用反射生成的lambda包含一个"硬编码"日期,而在"手工制作" lambda表达式,我必须使用" new DateTime(...)"。

因此单元测试失败并显示以下消息(我剪切消息以仅保留有趣的部分):

  

预期:< x => (...)AndAlso(x.Date< = new DateTime(2015,1,1)))>

     

但是:< x => (...)AndAlso(x.Date< = 01/01/2015 00:00:00))>

我的断言如下:

Assert.AreEqual(expectedWhere, request.Filter);

在哪里"期待哪里"是"手工制作" lambda和" request.Filter"是生成的lambda。

是否有解决方案(like in VB.NET)来创建我的lambda表达式:

Expression<Func<Model, bool>> expectedWhere = x => (...) && (x.Date <= [01/01/2015 00:00:00])

我已经测试过使用外部变量,DateTime.Now或常量(不是由.NET框架管理)。

编辑:

这是一个简单的小提示,显示我的问题:https://dotnetfiddle.net/fKccY3

代码:

ParameterExpression param = Expression.Parameter(typeof(Model), "x");
var property = Expression.Property(param, "Date");
ConstantExpression constant = Expression.Constant(new DateTime(2015, 1, 1), typeof(DateTime));

Expression finalExpression = Expression.LessThanOrEqual(property, constant);

var tree = Expression.Lambda<Func<Model, bool>>(finalExpression, param);
Console.WriteLine(tree);

Expression<Func<Model, bool>> handMaidExpression = x => x.Date == new DateTime(2015, 1, 1);

Console.WriteLine(handMaidExpression);

1 个答案:

答案 0 :(得分:4)

假设您真的想要生成一个带有ConstantExpression的合适表达式树,我认为您在使用实际的lambda表达式时遇到了麻烦。但是,您可以通过使用lambda表达式为其 rest 构建表达式树,并手动完成其余操作,从而合理地构建相关表达式树。这是一个简短而完整的例子:

using System;
using System.Linq.Expressions;

public class Model
{
    public string Name { get; set; }
    public DateTime Date { get; set; }
}

public class Test
{
    public static void Main()
    {
        Expression<Func<Model, bool>> original = x => x.Name == "Fred";
        var parameter = original.Parameters[0];
        var dateClause = Expression.LessThanOrEqual(
            Expression.Property(parameter, "Date"),
            Expression.Constant(new DateTime(2015, 1, 1), typeof(DateTime)));
        var combined = Expression.AndAlso(original.Body, dateClause);
        var tree = Expression.Lambda<Func<Model, bool>>(combined, parameter);
        Console.WriteLine(tree);
    }
}

输出:

x => ((x.Name == "Fred") AndAlso (x.Date <= 01/01/2015 00:00:00))

如果您需要在多个地方使用它,您可以相当轻松地将其构建为实用程序方法。