我想阅读表达式树中某些属性的值,我可以进行一些计算。
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;
}
答案 0 :(得分:0)
您似乎正在使用数据库查询提供程序(LINQ2SQL,EF等)
在尝试使用表达式来解决问题之前,您需要确保查询提供程序能够理解表达式。在您的情况下,许多Math
方法可以转换为T-SQL有效语句。此外,如果您正在使用实体框架,您可能希望利用System.Data.Objects.SqlClient.SqlFunctions
类创建表达式并在SQL Server端执行逻辑以对抗本机T-SQL函数。
现在,在表达式树上要理解的一点是,无法从构造表达式中获取值,除非这是LambdaExpression
,一旦编译后调用它,在你的情况下你可以获得bool
值。
如果需要使用价格值,则需要创建更多表达对其他逻辑的调用的表达式,在您的示例中,调用Sqrt
类的静态Math
方法。
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;
}
正如您所看到的,所有逻辑都是表达式,并且提供程序可以使用整个表达式并将其转换为目标进程可以理解的语法。先前的表达式生成 p => Math.Sqrt((double)p.Price) > 4d