Lambda表达式访问对象的属性,该对象是c#中另一个对象的属性

我有这两个class:

public class Contratos { //... public int EntidadeFinanceiraId { get; set; } [Column("Nome")] public EntidadesFinanceiras entidadeFinanceira { get; set; } //... } public class EntidadesFinanceiras { [Key] public int ID { get; set; } public string Nome { get; set; } //... } 

并希望以Contratos.entidadeFinanceira.Nome为基础过滤Contratos列表。 这是根据用户选择的属性过滤列表的方法的一部分。

  public IQueryable applyLambdaFilter(string val, string col, string oper, IQueryable contratosList) { if (!string.IsNullOrWhiteSpace(val)) { string typeName; string columnName; Type propType; string[] propName = col.Split(new[] { '.' }); if (propName.Count() > 1) { typeName = "GAcordos.Models." + propName[0]; //entidadeFinanceira columnName = propName[1]; //Nome propType = Type.GetType("GAcordos.Models.Contratos").GetProperty(propName[0]).PropertyType.GetProperty(columnName).PropertyType; //String } else { typeName = "GAcordos.Models.Contratos"; columnName = propName[0]; //Other Contratos property propType = Type.GetType(typeName).GetProperty(columnName).PropertyType; } if (propType != null) { var fixedItem = Comparators.getFixedItemWithType(val, propType); var param = Expression.Parameter(typeof(GAcordos.Models.Contratos), "x"); var body = Expression.Equal(Expression.PropertyOrField(param, col.ToString()), fixedItem, false, Type.GetType("GAcordos.Helpers.Comparators").GetMethod(oper, new Type[] { propType, propType })); var lambda = Expression.Lambda<Func>(body, param); contratosList = contratosList.Where(lambda.Compile()).AsQueryable(); } } return contratosList; } 

当方法执行时抛出exception‘entidadeFinanceira.Nome’不是该行上类型’GAcordos.Models.Contratos’的成员

 var body = Expression.Equal(Expression.PropertyOrField(param, col.ToString()), fixedItem, false, Type.GetType("GAcordos.Helpers.Comparators").GetMethod(oper, new Type[] { propType, propType })); 

但是,如果我直接写表达式:

 contratosList = contratosList.Where(x => x.entidadeFinanceira.Nome == val); 

它工作正常。

那么,我如何构建lambda表达式x => x.property.property == constVal?

简单地说,您需要PropertyOrField两种用途。

手动构造, x => x.Foo.Bar == constVal是:

 var param = Expression.Parameter(typeof(ObjectType), "x"); var lambda = Expression.Lambda>( Expression.Equal( Expression.PropertyOrField( Expression.PropertyOrField(param, "Foo"), "Bar" ), Expression.Constant(constVal, constValType) ), param); 

(请注意,如果constValnull ,则包含constValType很重要;这可以避免许多意外问题)

似乎在打电话时

 Expression.PropertyOrField(param, col.ToString()) 

变量col包含“entidadeFinanceira.Nome”。 您可以重复使用上面所做的所有分割,并执行以下操作:

 Expression property = param; foreach(var pName in propName) { property = Expression.PropertyOrField(property, pName); } 

现在表达式property应该是正确的,您可以使用它来构建body表达式:

 var body = Expression.Equal( property, fixedItem, false, Type .GetType("GAcordos.Helpers.Comparators") .GetMethod(oper, new Type[] { propType, propType }) );