尝试使用通过 LinqKit 创建的基本表达式的异常

Exception trying to use a basic Expression created with LinqKit

我正在尝试使用 LinqKit 强制 ef-core 参数化它认为常量的值,如 this article 中所述。

尝试应用 on github 中描述的 PredicateBuilder 示例时,出现异常。这是我的代码:

    private async Task getWallets()
    {
        var query =
            from w in _context.Wallets.AsExpandable()
            where w.WalletItems.Any(hasItems().Compile())
            select w;

        var result = await query.ToListAsync();
    }

    private Expression<Func<WalletItem, bool>> hasItems()
    {
        var predicate = PredicateBuilder.New<WalletItem>();
        var ids = new string[] { "A", "B" };

        foreach (var id in ids)
        {
            predicate = predicate.Or(wi => wi.ExternalId == id);
        }
        return predicate;            
    }

点击 ToListAsync() 时出现以下异常:

System.NotSupportedException: 'Could not parse expression 'w.WalletItems.Any(__Compile_0)': The given arguments did not match the expected arguments: Object of type 'System.Linq.Expressions.TypedParameterExpression' cannot be converted to type 'System.Linq.Expressions.LambdaExpression'.'

我是 运行 ASP.NET Core 2.1 应用程序 (netcoreapp2.1) 中的代码,使用以下软件包:

非常感谢任何帮助。

您在示例中缺少的是所有 Expression<Func<..>> 都是参数或局部变量的事实。而行

where w.WalletItems.Any(hasItems().Compile())

实际上并没有调用 hasItems 方法,而是在查询表达式树中向它发出 MethodCallExpression (i.e. Expression.Call),这是 LINQKit Expand 实现无法识别的不同类型的表达式,从而导致 EF Core 不支持表达。

解决方法是将方法调用结果放入局部变量中,并在查询表达式树中使用该变量:

var hasItemsExpr = hasItems();

var query =
    from w in _context.Wallets.AsExpandable()
    where w.WalletItems.Any(hasItemsExpr.Compile())
    select w;