如何表达 .Any(y => y.Name == "val"));在表达式树中?

How to express .Any(y => y.Name == "val")); within an expression tree?

我正在尝试创建 DbSet LINQ 过滤器。 我使用表达式是为了减少由过滤器选项和过滤器属性的独特组合引起的代码行数。

我能够轻松地将其应用于 DbSest 中对象的属性(工作代码粘贴在下面)。但是当我试图表达时,我遇到了障碍。 dbSet.Where(x => x.listProp.Any(y => y.Name == "val")); 建表达式树的时候不知道怎么表达.Any(...)

目前我正在尝试遵循 中的解决方案,但是当我到达 var anyCall = ... 时遇到以下问题:System.InvalidOperationException: 'No generic method 'Any' on type 'System.Linq.Queryable' is compatible with the supplied type arguments and arguments. No type arguments should be provided if the method is non-generic. '

这是我目前拥有的。

private IQueryable<dbo.Transaction> _FilterTransactionPartyType(ParameterExpression param, IQueryable<Transaction> query, string transactionPartyType)
{

    MemberExpression expM2M = Expression.PropertyOrField(param, "Parties");

    Type tM2M = typeof(M2M_Transactions_Party);
    ParameterExpression paramM2m = Expression.Parameter(tM2M, "m2m");

    //Any(m2m => m2m.Party.Name == "dd" && m2m.PartyType.Name = "dd")
    System.Reflection.PropertyInfo piParty = tM2M.GetProperty("Party");
    System.Reflection.PropertyInfo piPartyName = piParty.PropertyType.GetProperty("Name");
    System.Reflection.PropertyInfo piPartyType = tM2M.GetProperty("TransactionPartyType");
    System.Reflection.PropertyInfo piPartyTypeName = piPartyType.PropertyType.GetProperty("Name");

    MemberExpression expPartyType = Expression.Property(paramM2m, piPartyType);
    MemberExpression expPartyTypeName = Expression.Property(expPartyType, piPartyTypeName);

    ConstantExpression expPartyTypeValue = Expression.Constant(transactionPartyType, typeof(string));
    BinaryExpression isPartyTransactionType = Expression.Equal(expPartyTypeName, expPartyTypeValue);

    MemberExpression expParties = Expression.Property(paramM2m, piParty);
    MemberExpression expParty = Expression.Property(expParties, piPartyName);

    BinaryExpression isParty = _Filter(expParty);

    BinaryExpression isPartyAndType = Expression.AndAlso(isParty, isPartyTransactionType);
    Expression<Func<M2M_Transactions_Party, bool>> internalLambda = Expression.Lambda<Func<M2M_Transactions_Party, bool>>(isPartyAndType, paramM2m);


    // book.properties.Any(bookProperty => bookProperty.type.key == "lingerie" && bookProperty.value == "1")
    var anyCall = Expression.Call(
        typeof(Queryable), "Any", new[] { tM2M },
        expM2M, internalLambda
    );
    // book => book.properties.Any(...)
    var lambda = Expression.Lambda<Func<Transaction, bool>>(anyCall, param);

    return query.Where(lambda);

}

我发现了我的问题所在。

有一个问题是我使用了 typeof(Queryable) 而不是 typeof(Enumerable) ,我为任何查看我上面的方法的人确定的另一个问题是我在应该传递 IQueryable 的时候传递了 IQueryable在使用这个 post (combining-two-expressions-expressionfunct-bool)

之后刚刚返回 Expression<Func<Transaction, bool> 并连接它们

这是我目前的方法

private Expression<Func<Transaction, bool>> _FilterTransactionPartyType(ParameterExpression param, string transactionPartyType)
{
    MemberExpression expM2M = Expression.PropertyOrField(param, "Parties");

    Type tM2M = typeof(M2M_Transactions_Party);
    ParameterExpression paramM2m = Expression.Parameter(tM2M, "m2m");

    System.Reflection.PropertyInfo piParty = tM2M.GetProperty("Party");
    System.Reflection.PropertyInfo piPartyName = piParty.PropertyType.GetProperty("Name");
    System.Reflection.PropertyInfo piPartyType = tM2M.GetProperty("TransactionPartyType");
    System.Reflection.PropertyInfo piPartyTypeName = piPartyType.PropertyType.GetProperty("Name");

    MemberExpression expPartyType = Expression.Property(paramM2m, piPartyType);
    MemberExpression expPartyTypeName = Expression.Property(expPartyType, piPartyTypeName);

    ConstantExpression expPartyTypeValue = Expression.Constant(transactionPartyType, typeof(string));
    BinaryExpression isPartyTransactionType = Expression.Equal(expPartyTypeName, expPartyTypeValue);

    MemberExpression expParties = Expression.Property(paramM2m, piParty);
    MemberExpression expParty = Expression.Property(expParties, piPartyName);

    BinaryExpression isParty = _Filter(expParty);

    BinaryExpression isPartyAndType = Expression.AndAlso(isParty, isPartyTransactionType);
    Expression<Func<M2M_Transactions_Party, bool>> internalLambda = Expression.Lambda<Func<M2M_Transactions_Party, bool>>(isPartyAndType, paramM2m);

    MethodCallExpression anyCall = Expression.Call(
        typeof(Enumerable), "Any", new[] { tM2M },
        expM2M, internalLambda
    );

    Expression<Func<Transaction, bool>> lambda = Expression.Lambda<Func<Transaction, bool>>(anyCall, param);

    return lambda;
}