obj.Prop" to "parent => parent.obj.Prop"? " /> Refactor "obj => obj.Prop" to "parent => parent.obj.Prop"?
Refactor the LINQ expression "obj => obj.Prop" into "parent => parent.obj.Prop"
When modifying an existing LINQ expression of type Expression<Func<object>>
to accept a parent class, challenges arise when the expression involves nested properties. The existing ExpressionFromField<TModel>
method has problems handling expressions like cust => cust.Address.State
because it cannot explicitly access the intermediate object (cust.Address
in this case).
The solution lies in expression composition, which combines multiple expressions into one. Here’s the step-by-step method:
1. Expression combination method
Define a static method named Compose<T, TIntermediate, TResult>
that accepts three expression delegates:
<code class="language-csharp">public static Expression<Func<T, TResult>> Compose<T, TIntermediate, TResult>( this Expression<Func<T, TIntermediate>> first, Expression<Func<TIntermediate, TResult>> second) { // 用第二个表达式的参数替换第一个表达式的参数出现 return Expression.Lambda<Func<T, TResult>>( second.Body.Replace(second.Parameters[0], first.Body), first.Parameters[0]); }</code>
2. Expression replacement
Creates a class named ReplaceVisitor
that is derived from ExpressionVisitor
:
<code class="language-csharp">public class ReplaceVisitor : ExpressionVisitor { private readonly Expression from, to; public ReplaceVisitor(Expression from, Expression to) { this.from = from; this.to = to; } public override Expression Visit(Expression ex) { if (ex == from) return to; else return base.Visit(ex); } }</code>
Add an extension method Expression
to the Replace
class:
<code class="language-csharp">public static Expression Replace(this Expression ex, Expression from, Expression to) { return new ReplaceVisitor(from, to).Visit(ex); }</code>
3. Application combination
With the combination and substitution methods in place, you can now construct new expressions:
<code class="language-csharp">// 选择属性的表达式: Expression<Func<Customer, object>> propertySelector = cust => cust.Name; // 从模型中选择对象的表达式 Expression<Func<Model, Customer>> modelSelector = model => model.Customer; // 组合表达式 Expression<Func<Model, object>> magic = modelSelector.Compose(propertySelector);</code>
By combination...
This revised response maintains the original language and structure, rewording phrases and sentences to achieve paraphrasing without altering the meaning. The image remains in its original format and location.
The above is the detailed content of How to Rework a LINQ Expression from 'obj => obj.Prop' to 'parent => parent.obj.Prop'?. For more information, please follow other related articles on the PHP Chinese website!