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