简体   繁体   English

.NET Core 3 中的 EF LINQ 查询问题

[英]Issue with EF LINQ query in .NET Core 3

I have upgraded my web app to NET Core 3 and some EF LINQ queries that were returning values correctly in NET Core 2 now are erroring.我已将我的 web 应用程序升级到 NET Core 3,一些在 NET Core 2 中正确返回值的 EF LINQ 查询现在出错了。 I have the following code in my OrderManager class:我的 OrderManager class 中有以下代码:

 private TResult GetOrder<TResult>(Func<Order, bool> condition, Func<Order, TResult> selector)
    {
        return _context.Orders
            .Where(x => condition(x))
                .Include(x => x.OrderStocks)
                    .ThenInclude(x => x.Stock)
                        .ThenInclude(x => x.Product)
                            .Select(selector).FirstOrDefault();
    }

    public TResult GetOrderById<TResult>(int id, Func<Order, TResult> selector)
    {
        return GetOrder(order => order.Id == id, selector);
    }

    public TResult GetOrderByReference<TResult>(string reference, Func<Order, TResult> selector)
    {
        return GetOrder(x => x.OrderRef == reference, selector);
    }

Looks like dotnet 3 doesn't like that.Where statement:看起来 dotnet 3 不喜欢那样。Where 语句:

System.InvalidOperationException: 'The LINQ expression 'DbSet.Where(o => Invoke(__condition_0, o[Order]) )' could not be translated. System.InvalidOperationException:“无法翻译 LINQ 表达式 'DbSet.Where(o => Invoke(__condition_0, o[Order]) )”。 Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync().以可翻译的形式重写查询,或通过插入对 AsEnumerable()、AsAsyncEnumerable()、ToList() 或 ToListAsync() 的调用显式切换到客户端评估。 See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.'有关详细信息,请参阅https://go.microsoft.com/fwlink/?linkid=2101038

Does anyone know how this query could be re-written correctly?有谁知道如何正确重写此查询? I have tried to add AsEnumerable() in line: return _context.Orders but thats not the fix, I am a bit blocked here as I am not an expert in LINQ.我试图在行中添加 AsEnumerable():return _context.Orders 但这不是解决方法,我在这里有点受阻,因为我不是 LINQ 的专家。

GetOrder needs to take Expression<Func<Order, bool>> as condition parameter not Func<Order, bool> : GetOrder需要将Expression<Func<Order, bool>>作为condition参数而不是Func<Order, bool>

private TResult GetOrder<TResult>(Expression<Func<Order, bool>> condition, Func<Order, TResult> selector)

After changing the parameter you will need to change Where clause also:更改参数后,您还需要更改Where子句:

_context.Orders
        .Where(condition)

It seems previously your query was executed on client side, see the breaking changes list .以前您的查询似乎是在客户端执行的,请参阅中断更改列表

Though it should be fine to have Func for selector cause it is last statement in the query, but bear in mind that it will fetch all columns into memory and then preform mapping using needed ones.尽管为selector设置Func应该没问题,因为它是查询中的最后一条语句,但请记住,它将所有列提取到 memory 中,然后使用所需的列进行映射。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM