You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在LINQ表达式树中实现.Any()方法以构建DbSet筛选逻辑

C# 表达式树构建Any方法调用异常修复方案

错误原因

No generic method 'Any' on type 'System.Linq.Queryable' is compatible异常核心原因是:实体导航属性Parties的类型为实现IEnumerable<M2M_Transactions_Party>的集合(常见为ICollection<M2M_Transactions_Party>),不属于IQueryable<T>类型,无法匹配Queryable.Any的方法签名,需要改为调用Enumerable.Any方法。

修正方案

只需要将Expression.Call调用的方法所属类从typeof(Queryable)改为typeof(Enumerable)即可,修改后的对应代码段如下:

// 将原来的typeof(Queryable)替换为typeof(Enumerable)即可
var anyCall = Expression.Call(
    typeof(Enumerable), "Any", new[] { tM2M },
    expM2M, internalLambda
);

完整修正后代码

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 匹配规则 && m2m.PartyType.Name == transactionPartyType
    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);

    // 核心修改:将Queryable改为Enumerable,匹配导航属性的集合类型
    var anyCall = Expression.Call(
        typeof(Enumerable), "Any", new[] { tM2M },
        expM2M, internalLambda
    );
    
    var lambda = Expression.Lambda<Func<Transaction, bool>>(anyCall, param);
    return query.Where(lambda);
}

扩展说明

如果遇到源是IQueryable<T>类型需要调用Queryable.Any的场景,需要先将集合转为IQueryable,对应代码如下:

// 先调用AsQueryable将集合转为IQueryable类型
var asQueryableCall = Expression.Call(
    typeof(Queryable), "AsQueryable", new[] { tM2M },
    expM2M
);
// 再调用Queryable.Any
var anyCall = Expression.Call(
    typeof(Queryable), "Any", new[] { tM2M },
    asQueryableCall, internalLambda
);

内容的提问来源于stack exchange,提问作者Mandelbrotter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 00:09:01