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

标签 c# lambda expression

我有这两个类:

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<Models.Contratos> applyLambdaFilter(string val, string col, string oper, IQueryable<Models.Contratos> 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<GAcordos.Models.Contratos, bool>>(body, param);
                contratosList = contratosList.Where(lambda.Compile()).AsQueryable();
            }
        }
        return contratosList;
    }

当方法执行时它抛出异常'entidadeFinanceira.Nome' is not a member of type 'GAcordos.Models.Contratos' on the line

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<Func<ObjectType, bool>>(
    Expression.Equal(
        Expression.PropertyOrField(
           Expression.PropertyOrField(param, "Foo"), "Bar"
        ), Expression.Constant(constVal, constValType)
    ), param);

(请注意,在 constValnull 的情况下,包含 constValType 很重要;这样可以避免很多意外问题)

关于c# - Lambda表达式访问一个对象的属性,该属性是c#中另一个对象的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6384500/

相关文章:

java - 我正在尝试通过使用 Java 8 流遍历嵌入式列表来返回数据

java - 如何在 jdk 7 或更旧版本中使用 lambda 表达式

c# - 从 Expression<Func<TModel, TProperty>> 转换为 Expression<Func<TModel, bool>>

function - 表达式与函数之间的差异

c# - 根据平台加载 x64 或 x86 DLL?

c# - 在.Net核心控制台应用程序中触发后台服务ExecuteAsync方法

c# - .NET DSACryptoServiceProvider key 大小

c#检查列表中的所有字符串是否相同

haskell - 将运算符与 lambda 函数关联的映射

Python:数学表达式解析