C# 如何读取表达式树中属性的值?

C# 如何读取表达式树中属性的值?,c#,expression-trees,C#,Expression Trees,我想读取表达式树中一些属性的值,我可以进行一些计算 var products = db.Products .Where(GetPredicate()) .ToList(); private Expression<Func<Product, bool>> GetPredicate() { ParameterExpression pe = Expression.Parameter(typeof(Product), "p"); Express

我想读取表达式树中一些属性的值,我可以进行一些计算

var products = db.Products
    .Where(GetPredicate())
    .ToList();

private Expression<Func<Product, bool>>  GetPredicate()
{
    ParameterExpression pe = Expression.Parameter(typeof(Product), "p");
    Expression exp0 = Expression.Property(pe, "Price");

   //I'd like to know the value of the 'Price'
   // so I can do some calculation, then check whether 
   //this particular product meet the criteria...

   Expression body = Expression.Constant(Result);  //result is a boolean
   var expr = Expression.Lambda<Func<Product, bool>>(body, new ParameterExpression[] { pe });
        return expr;

}
var products=db.products
.Where(GetPredicate())
.ToList();
私有表达式GetPredicate()
{
ParameterExpression pe=表达式参数(产品类型),“p”);
表达式exp0=表达式属性(pe,“价格”);
//我想知道“价格”的价值
//所以我可以做一些计算,然后检查
//这种特殊的产品符合标准。。。
Expression body=Expression.Constant(Result);//结果是布尔值
var expr=Expression.Lambda(body,新参数Expression[]{pe});
返回表达式;
}

您似乎在使用数据库查询提供程序(LINQ2SQL、EF等)

在尝试使用表达式解决问题之前,需要确保查询提供程序理解该表达式。在您的例子中,许多
Math
方法可以转换为T-SQL有效语句。此外,如果您使用的是实体框架,那么您可能希望利用
System.Data.Objects.SqlClient.SqlFunctions
类创建一个表达式,并在SQL Server端针对本机T-SQL函数执行逻辑

现在,在表达式树上需要理解的是,除非这是
LambdaExpression
,否则无法从构造表达式中获取值,编译后调用它,在您的示例中可以获取
bool

如果需要使用price值,则需要创建更多表达式来表示对其他逻辑的调用,在您的示例中,这些表达式调用
Math
类的静态
Sqrt
方法

private Expression<Func<Product, bool>> GetPredicate()
{
   var pe = Expression.Parameter(typeof(Product), "p");
   var price = Expression.Property(pe, "Price");
   var priceDouble = Expression.Convert(price, typeof(double));
   var sqrtMethod = typeof(Math).GetMethod("Sqrt");
   var sqrtCall = Expression.Call(sqrtMethod, priceDouble);
   var constant = Expression.Constant(4d);
   var gtThan = Expression.GreaterThan(sqrtCall, constant);

   var lambda = Expression.Lambda<Func<Product, bool>>(gtThan, pe);
   return lambda;
}
私有表达式GetPredicate()
{
var pe=表达式参数(产品类型),“p”);
var价格=表达式属性(pe,“价格”);
var priceDouble=表达式.Convert(price,typeof(double));
var sqrtMethod=typeof(Math).GetMethod(“Sqrt”);
var sqrtCall=Expression.Call(sqrtMethod,priceDouble);
var常数=表达式常数(4d);
var gtThan=表达式.GreaterThan(sqrtCall,常量);
var lambda=表达式.lambda(gtThan,pe);
返回lambda;
}

正如您所看到的,所有逻辑都是一个表达式,提供者可以使用整个表达式并将其转换为目标进程可以理解的语法。前面的表达式生成
p=>Math.Sqrt((double)p.Price)>4d
您似乎正在使用数据库查询提供程序(LINQ2SQL、EF等)

在尝试使用表达式解决问题之前,需要确保查询提供程序理解该表达式。在您的例子中,许多
Math
方法可以转换为T-SQL有效语句。此外,如果您使用的是实体框架,那么您可能希望利用
System.Data.Objects.SqlClient.SqlFunctions
类创建一个表达式,并在SQL Server端针对本机T-SQL函数执行逻辑

现在,在表达式树上需要理解的是,除非这是
LambdaExpression
,否则无法从构造表达式中获取值,编译后调用它,在您的示例中可以获取
bool

如果需要使用price值,则需要创建更多表达式来表示对其他逻辑的调用,在您的示例中,这些表达式调用
Math
类的静态
Sqrt
方法

private Expression<Func<Product, bool>> GetPredicate()
{
   var pe = Expression.Parameter(typeof(Product), "p");
   var price = Expression.Property(pe, "Price");
   var priceDouble = Expression.Convert(price, typeof(double));
   var sqrtMethod = typeof(Math).GetMethod("Sqrt");
   var sqrtCall = Expression.Call(sqrtMethod, priceDouble);
   var constant = Expression.Constant(4d);
   var gtThan = Expression.GreaterThan(sqrtCall, constant);

   var lambda = Expression.Lambda<Func<Product, bool>>(gtThan, pe);
   return lambda;
}
私有表达式GetPredicate()
{
var pe=表达式参数(产品类型),“p”);
var价格=表达式属性(pe,“价格”);
var priceDouble=表达式.Convert(price,typeof(double));
var sqrtMethod=typeof(Math).GetMethod(“Sqrt”);
var sqrtCall=Expression.Call(sqrtMethod,priceDouble);
var常数=表达式常数(4d);
var gtThan=表达式.GreaterThan(sqrtCall,常量);
var lambda=表达式.lambda(gtThan,pe);
返回lambda;
}

正如您所看到的,所有逻辑都是一个表达式,提供者可以使用整个表达式并将其转换为目标进程可以理解的语法。前面的表达式生成
p=>Math.Sqrt((double)p.Price)>4d

您是否尝试使用该表达式。转换?在
GetPredicate
中创建表达式树时,可能存在重复的值您没有
Price
(因为您没有
Product
对象)。因此,在将实际值传递给已编译的表达式树之前,无法检索它。但您可以根据需要向表达式树添加某种比较和约束。如下所示:
Expression.Add(exp0,Expression.Constant(156))然后您可以检查返回值等。但您还不知道值,您只知道将比较您的输入值等。我是否遗漏了什么或不理解您的问题?@GeorgeAlexandria,因此应将
exp0
视为公式中使用的变量?我尝试了类似
Math.Sqrt(exp0)的东西并出现错误:
无法将'System.Linq.Expression.Expression'转换为'double'
exp0
应该是
Expression
,如果您想在表示为
Expression
的公式中使用它。让我展示一个简单的例子:您有
(值+4)*3+2
。这是一个包含一个输入参数的简单公式。您可以将其表示为表达式树:
var expVal=Expression.Parameter(typeof(int));Add(Expression.Multiply(Expression.Add(expVal,Expression.Constant(4)),Expression.Constant(3)),Expression.Constant(2))。因此,您的示例
Math.Sqrt(value)
也可以表示为表达式树。您是否尝试使用表达式.Convert?当y