1

我有以下 lambda 表达式

    var expr = a => (a.Name == "Alex" && a.DateCreated < DateTime.Now.AddHours(2))

我想在字符串中获取具有运行时值的表达式主体,如果我调用 expr.Body.ToString() 我得到以下字符串作为回报。

    {((a.Name == "Alex") AndAlso (a.DateCreated < DateTime.Now.AddHours(2)))}

所以只是为了澄清我希望得到 DateTime.Now.AddHours(2) 的值。在过去的几个晚上,我一直在疯狂地搜索网络,但没有任何结果。这可能是因为我不知道要搜索什么。希望你们能帮忙:)

4

2 回答 2

2

您需要将 DateTime 调用移出 lambda:

DateTime endDate = DateTime.Now.AddHours(2);
Expression<Func<YourClass, bool>> expr = a => (a.Name == "Alex" && a.DateCreated < endDate);

即使这样,您也会在表达式中显示闭包,而不是值。

要将特定日期作为打印值,您需要一个常量,即:

Expression<Func<YourClass, bool>> expr = a => (a.Name == "Alex" && a.DateCreated < DateTime.Parse("10/2/2012"));

这将显示DateTime.Parse调用,但至少仍然显示值(因为它是表达式中的常量。)

构建表达式时,DateTime属性和方法 ( Nowand AddHours) 成为表达式本身的一部分。这也发生在闭变量上。该表达式必须包含构建完整 lambda 所需的所有语句,包括DateTime.Now.AddHours(2).

这是设计使然 -DateTime.Now.AddHours()如果您将其转换为实体框架查询,则需要在服务器上解决,例如,因为AddHours 是 Canonical Functions 之一。如果将其替换为常数,则其行为将不符合预期。

于 2012-08-15T16:55:14.710 回答
0

下面的代码有效,但我不确定你是否真的想使用它。

Expression<Func<A,bool>> expr = a => (a.Name == "Alex" && a.DateCreated < DateTime.Now.AddHours(2));

var expr1 = expr.Body as BinaryExpression;
var expr2 = expr1.Right as BinaryExpression; //a.DateCreated < DateTime.Now.AddHours(2)
var expr3 = expr2.Right as MethodCallExpression; //DateTime.Now.AddHours(2)

var obj = expr3.Object as MemberExpression; //DateTime.Now
var pi = obj.Member as PropertyInfo;
var dt = pi.GetValue(null); //Call DateTime.Now


var arg = expr3.Arguments[0] as ConstantExpression;
var result = expr3.Method.Invoke(dt, new object[] { arg.Value }); //Call AddHours

-

public class A
{
    public string Name { set; get; }
    public DateTime DateCreated { set; get; }
}
于 2012-08-15T17:35:01.383 回答