gpt4 book ai didi

c# - 从属性中检索表达式并将其添加到表达式树

转载 作者:太空狗 更新时间:2023-10-30 00:59:00 24 4
gpt4 key购买 nike

我已尝试简化此示例,因为我正在使用的实际代码更为复杂。因此,尽管这个示例可能看起来很愚蠢,但请耐心等待。假设我正在使用 AdventureWorks 数据库,我决定将一个名为 Blarg 的属性添加到 Product 表,该表返回一个包含我想要的代码的表达式在几个地方使用:

public partial class Product
{
public Expression<Func<Product, string>> Blarg
{
get { return product => product.ProductModelID.HasValue ? "Blarg?" : "Blarg!"; }
}
}

我想做的是创建一个表达式表达式树,让它从 Product.Blarg 中获取表达式,然后按结果分组。像这样:

var productParameter = Expression.Parameter(typeof(Product), "product");

// The Problem
var groupExpression = Expression.Lambda<Func<Product, string>>(
Expression.Invoke(
Expression.Property(productParameter, "Blarg"),
productParameter),
productParameter);

using (AdventureWorksDataContext db = new AdventureWorksDataContext())
{
var result = db.Products.GroupBy(groupExpression).ToList();
// Throws ArgumentException: "The argument 'value' was the wrong type.
// Expected 'System.Delegate'.
// Actual 'System.Linq.Expressions.Expression`1[System.Func`2[LINQ_Test.Product,System.String]]'."
}

显然 groupExpression 是不正确的(请参阅异常的代码注释),但我不确定我应该怎么做。我以为我说的是“从 product.Blarg 中获取表达式,执行它,然后返回字符串结果。”不过,我想那不是我真正要说的。我仍在尝试找出表达式树。知道如何实现吗?

最佳答案

当您调用 Expression.Invoke 时,第一个参数必须是现有的 LambdaExpression - 它不能是 Expression LambdaExpression。或者换句话说:它不会评估 Product.Blarg 每行 并且每次都使用不同的子表达式。

相反,您将首先检索此 lambda,如果您只知道它的名称,则可能将其设为 static 并通过反射访问它:

var lambda = (LambdaExpression) typeof(Product)
.GetProperty("Blarg").GetValue(null,null);

并将lambda作为参数传递给Expression.Invoke;这里有一个完整的 LINQ-to-Objects 示例展示了这一点(通过 AsQueryable()):

using System;
using System.Linq;
using System.Linq.Expressions;
public partial class Product
{
public static Expression<Func<Product, string>> Blarg
{
get { return product => product.ProductModelID.HasValue ? "Blarg?" : "Blarg!"; }
}
public int? ProductModelID { get; set; }

static void Main()
{
var lambda = (LambdaExpression)typeof(Product)
.GetProperty("Blarg").GetValue(null, null);

var productParameter = Expression.Parameter(typeof(Product), "product");

// The Problem
var groupExpression = Expression.Lambda<Func<Product, string>>(
Expression.Invoke(
lambda,
productParameter),
productParameter);

var data = new[] {
new Product { ProductModelID = 123},
new Product { ProductModelID = null},
new Product { ProductModelID = 456},
};
var qry = data.AsQueryable().GroupBy(groupExpression).ToList();
}
}

关于c# - 从属性中检索表达式并将其添加到表达式树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1599999/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com