【发布时间】:2016-06-02 21:49:39
【问题描述】:
我有一个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 member 行上收到指定成员不存在的错误——这是真的,因为该处的正文指的是父母的孩子(Customer)而不是包含该成员的项目(@987654336 @)。
这是我希望我能做的:
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 方法的参数,这限制了可能的解决方案。
【问题讨论】:
-
为什么不能从父级的子级属性中调用这些表达式,而不是让它们发生变异以直接在父级上工作?
-
使用
parent => (cust => cust.Name)(parent.Customer)会简单得多。 -
@TravisJ,我正在使用所有这些来连接基类,所以很少有细节是预先知道的。可能有更好的方法来做我正在做的事情,但这种方法会奏效。
-
@poke,我不确定那是什么。您是否将客户视为一种表达方式?你能用未知的表达式做同样的事情吗(我不知道
parent、cust的类型,或者Name的字段或类型。
标签: c# asp.net-mvc linq linq-expressions