EF Core 3 Linq 无法翻译

Posted

技术标签:

【中文标题】EF Core 3 Linq 无法翻译【英文标题】:EF Core 3 Linq could not be translated 【发布时间】:2020-03-11 22:30:26 【问题描述】:

我尝试在 ef core 3.0 中构建一个从数据库服务器获取完整进程的查询

 IEnumerable<int> stIds = stateIds;
  var rtables = await db.Order.
                Join(db.OrderDetail, order => order.OrderId, orderdetail => orderdetail.OrderId, (order, orderdetail) => new  order, orderdetail ).
                Where(x => x.order.SellerId == sellerId && stIds.Contains(x.orderdetail.OrderStateId)&&x.order.RtableId != null)
                .GroupBy(x =>             
                x.order.RtableId               
                )
                .Select(x => new RtableState  RtableId = x.Key ?? 0, OrderStateId = x.OrderByDescending(x => x.orderdetail.OrderStateId).Select(x => x.orderdetail.OrderStateId).FirstOrDefault() ).ToListAsync();

我收到此错误:

"消息": "处理 LINQ 表达式 'AsQueryablef__AnonymousType52>(OrderByDescendingf__AnonymousType52, int>(\r\n 来源:NavigationTreeExpression\r\n 值:默认值(IGrouping, f__AnonymousType52>)\ r\n Expression: (Unhandled parameter: e), \r\n keySelector: (x) => x.orderdetail.OrderStateId))' by 'NavigationExpandingExpressionVisitor' 失败。这可能表示 EF Core 中的错误或限制。有关更多详细信息,请参阅https://go.microsoft.com/fwlink/?linkid=2101433。", “内”:“”

我知道查询对于 EF Core 3.0 来说太复杂了,但这是一个错误还是应该不起作用?

我的解决方案是拆分请求。

IEnumerable<int> stIds = stateIds;
            var rtableStatesServer = await db.Order.
                Join(db.OrderDetail, order => order.OrderId, orderdetail => orderdetail.OrderId, (order, orderdetail) => new  order, orderdetail ).
                Where(x => x.order.SellerId == sellerId && stIds.Contains(x.orderdetail.OrderStateId) && x.order.RtableId != null)
                .GroupBy(x => new RtableState
                
                    RtableId =

                x.order.RtableId ?? 0,
                    OrderStateId = x.orderdetail.OrderStateId
                )
                .Select(x => new RtableState  RtableId = x.Key.RtableId, OrderStateId = x.Key.OrderStateId ).ToListAsync();


            var rtableStates = rtableStatesServer.GroupBy(r => r.RtableId,
                        (key, value) => new RtableState
                        
                            RtableId = key,
                            OrderStateId = value.OrderByDescending(x=>x.OrderStateId).Select(x => x.OrderStateId).FirstOrDefault()
                        ).ToList();

【问题讨论】:

【参考方案1】:

如异常信息所示,问题是由表达式引起的

x.OrderByDescending(y => y.orderdetail.OrderStateId)
    .Select(y => y.orderdetail.OrderStateId)
    .FirstOrDefault()

其中xIGrouping&lt;,&gt;GroupBy 运算符生成。

这可能表示 EF Core 中存在错误或限制。

我认为这是一个限制,它可能永远不会被修复,因为包含除键和聚合表达式之外的表达式的 GroupBy 结果没有自然的 SQL 等效项。

一般的解决方案是尽可能避免使用GroupBy,并使用具有相关子查询的替代构造。但是这个特定的查询有简单的自然解决方案,因为表达式

set.OrderByDescending(item => item.Property).Select(item => itm.Property).FirstOfDefault() 

可以用

表示
set.Max(item => item.Property)

这是一个标准(因此支持聚合)。

将上述有问题的表达式替换为

x.Max(y => y.orderdetail.OrderStateId)

问题就解决了。

【讨论】:

谢谢,你是对的,我使用了 x.Max() 并且它有效!我客人想复杂。

以上是关于EF Core 3 Linq 无法翻译的主要内容,如果未能解决你的问题,请参考以下文章

Entityframework Core 3 linq表达式无法翻译

EF.Property 抛出“无法翻译 LINQ 表达式”

EF Core 仅查询 DateTimeOffset 的 DateTime 无法翻译;

[翻译] 介绍EF Core

[翻译] EF Core 概述

[翻译 EF Core in Action 1.6]你的第一个EF Core应用程序