c# – 将Linq表达式“obj => obj.Prop”转换为“parent => parent.obj.Prop”
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – 将Linq表达式“obj => obj.Prop”转换为“parent => parent.obj.Prop”,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3139字,纯文字阅读大概需要5分钟。
内容图文
![c# – 将Linq表达式“obj => obj.Prop”转换为“parent => parent.obj.Prop”](/upload/InfoBanner/zyjiaocheng/767/12f635444bb74027a8a0fec88198d11f.jpg)
我有一个Expression< Func< T,object>>类型的现有表达式;它包含像cust =>这样的值cust.Name.
我还有一个类型为T的字段的父类.我需要一个接受上述参数的方法,并生成一个以父类(TModel)作为参数的新表达式.这将用作MVC方法的表达式参数.
因此,cust => cust.Name成为parent => parent.Customer.Name.
同样,cust => cust.Address.State成为parent => parent.Customer.Address.State.
这是我的初始版本:
//note: the FieldDefinition object contains the first expression
//described above, plus the MemberInfo object for the property/field
//in question
public Expression<Func<TModel, object>> ExpressionFromField<TModel>(FieldDefinition<T> field)
where TModel: BaseModel<T>
{
var param = Expression.Parameter(typeof(TModel), "t");
//Note in the next line "nameof(SelectedItem)". This is a reference
//to the property in TModel that contains the instance from which
//to retrieve the value. It is unqualified because this method
//resides within TModel.
var body = Expression.PropertyOrField(param, nameof(SelectedItem));
var member = Expression.MakeMemberAccess(body, field.Member);
return Expression.Lambda<Func<TModel, object>>(member, param);
}
我当前收到的错误是当我有一个包含多个部分的字段时(即cust.Address.State而不仅仅是cust.Name).我在var成员行上得到一个指定成员不存在的错误 – 这是真的,因为那里的主体引用了父的子(Customer)而不是包含该成员的项(Address).
这就是我希望我能做到的:
public Expression<Func<TModel, object>> ExpressionFromField<TModel>(FieldDefinition<T> field)
where TModel: BaseModel<T>
{
var param = Expression.Parameter(typeof(TModel), "t");
var body = Expression.PropertyOrField(param, nameof(SelectedItem));
var IWantThis = Expression.ApplyExpressionToField(field.Expression, body);
return Expression.Lambda<Func<TModel, object>>(IWantThis, param);
}
任何帮助到达这一点将不胜感激.
编辑:这被标记为this question的可能重复;然而,唯一真正的相似之处是解决方案(实际上是相同的).组合表达式不是通过表达式访问嵌套属性的直观解决方案(除非一个人的理解是由某种经验引导的,不应该假设).我还编辑了这个问题,注意解决方案需要适合MVC方法的参数,这限制了可能的解决方案.
解决方法:
您正在寻找的是组合表达式的能力,就像您可以组合函数一样:
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]);
}
这依赖于以下方法将一个表达式的所有实例替换为另一个:
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);
}
}
public static Expression Replace(this Expression ex,
Expression from,
Expression to)
{
return new ReplaceVisitor(from, to).Visit(ex);
}
您现在可以选择一个属性的表达式:
Expression<Func<Customer, object>> propertySelector = cust => cust.Name;
以及从模型中选择该对象的表达式:
Expression<Func<CustomerModel, Customer>> modelSelector = model => model.Customer;
并撰写它们:
Expression<Func<Customer, object> magic = modelSelector.Compose(propertySelector);
内容总结
以上是互联网集市为您收集整理的c# – 将Linq表达式“obj => obj.Prop”转换为“parent => parent.obj.Prop”全部内容,希望文章能够帮你解决c# – 将Linq表达式“obj => obj.Prop”转换为“parent => parent.obj.Prop”所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。