如何将嵌套表达式的列表分解为单级表达式的列表

本文关键字:列表 表达式 单级 分解 嵌套 | 更新日期: 2023-09-27 18:11:24

假设我有一个List<Expression<Func<SomeModel, object>>>,看起来像这样:

x => x.Property1,
x => x.Property1.P1ChildProperty1,
x => x.Property1.P1ChildProperty2,
x => x.Property2,
x => x.Property2.P2ChildProperty1,
x => x.Property2.P2ChildProperty2,
x => x.Property2.P2ChildProperty3

有没有什么方法可以让我遍历这个列表,并生成一个新的列表集,这些列表只深度为一级,就像这样:

列表1:

x => x.Property1,
x => x.Property2

列表2:

y => y.P1ChildProperty1,
y => y.P1ChildProperty2

列表3:

z => z.P2ChildProperty1,
z => z.P2ChildProperty2,
z => z.P2ChildProperty3

如何将嵌套表达式的列表分解为单级表达式的列表

是的,有一种方法可以做到。但这取决于你的类结构。

var items = new List<Expression<Func<SomeModel, object>>>
            {
                x => x.Property1,
                x => x.Property1.P1ChildProperty1,
                x => x.Property1.P1ChildProperty2,
                x => x.Property2,
                x => x.Property2.P2ChildProperty1,
                x => x.Property2.P2ChildProperty2,
                x => x.Property2.P2ChildProperty3
            };
Func<LambdaExpression, Expression<Func<object, object>>> reBase = 
            x =>
            {
                var memExpr = (MemberExpression)x.Body;
                var param = Expression.Parameter(typeof(object), "x");
                var typedParam = Expression.Convert(param, memExpr.Member.DeclaringType);
                var property = Expression.Property(typedParam, memExpr.Member.Name);
                return Expression.Lambda<Func<object, object>>(property, param);
            };
var groupedItems = (from item in items
                    group item by ((MemberExpression)item.Body).Member.DeclaringType into g
                    select g.Select(x => reBase(x)).ToList()).ToList();

之后,groupedItems包含您想要的拆分的重新基于的列表。

问题是它要求声明类型。只有当您声明具有以下属性的类型时,这才会起作用:

  • SomeModel: Child1Property1, Child2Property2
  • <Child1>: P1ChildProperty1, P1ChildProperty2
  • <Child2>: P1ChildProperty1, P1ChildProperty2, P1ChildProperty3

我不确定这对你是否有帮助。也许你应该更深入地研究表达式树,找到一个更好的方法来分割你的列表。

请记住这将lambda签名从Func<SomeModel, object>更改为Func<object, object>