我有以下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)的值。过去几天我一直在疯狂地搜索网页而没有任何结果。这可能取决于我不知道要搜索什么。希望你们能够提供帮助:)
答案 0 :(得分: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
属性和方法(Now
和AddHours
)将成为表达式本身的一部分。闭环变量也会发生这种情况。表达式必须包括构建完整lambda所需的所有语句,包括DateTime.Now.AddHours(2)
。
这是设计 - 如果您将其转换为实体框架查询(例如AddHours is one of the Canonical Functions),则需要在服务器上解析DateTime.Now.AddHours()
。如果用常量换出它,它将不会按预期运行。
答案 1 :(得分: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; }
}