.NET Core 3.1 中的 Linq 表达式 GroupBy 错误

Posted

技术标签:

【中文标题】.NET Core 3.1 中的 Linq 表达式 GroupBy 错误【英文标题】:Error in Linq Expression GroupBy in .NET Core 3.1 【发布时间】:2021-08-30 06:24:15 【问题描述】:

将代码从 .NET Core 2.1 迁移到 3.1 后,以下 Linq 无法正常工作。它显示了 LinqExpression 中的 InvalidOperationException - GroupByShaperExpression

Message=The LINQ expression '(GroupByShaperExpression:
KeySelector: new  
    DepotNo = (g.DepotNo), 
    DepotName = (g.DepotName)
 , 
ElementSelector:(EntityShaperExpression: 
    EntityType: DepartmentWorkTime
    ValueBufferExpression: 
        (ProjectionBindingExpression: EmptyProjectionMember)
    IsNullable: False
)
)
    .Select(dd => new  
        id = (object)dd.DepotNo + "." + (object)dd.DepartmentID, 
        title = (object)dd.Depot.DepotNo + "." + dd.Department.DepartmentName
     )' could not be translated. 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(). 

我有两个模型和另一个视图模型

Depot Model
public class Depot
    
        [Key]
        public int DepotNo  get; set; 
        public string DepotName get;set;
`    

public class Department 
    
        [Key]
        public int DepartmentID get; set; 
        public string DepartmentName get;set; 
    

public class DepartmentWorkTime
    
        [Key]
        public int Id  get; set; 
        public int DepotNo  get; set; 
        public int DepartmentID  get; set; 
        public DepotModel Depot  get; set; 
       public DepartmentModel Department  get; set; 
    

我在Depot模型和Department模型中有以下记录

Depot Model
1, .AAAA Depot,
2, BBBB Depot,
4, CCCC Depot,


Department Model
1, Retail,
2, Office,
3, Field Staff,
4, Warehouse,


DepartmentWorkTime  List
1,1,1, Depot Model ,Department Model,
2,1,2, Depot Model ,Department Model,
3,1,4, Depot Model ,Department Model,

4,2,1, Depot Model ,Department Model,
5,2,2, Depot Model ,Department Model,
6,2,3, Depot Model ,Department Model,

7,4,1, Depot Model ,Department Model,

我正在尝试从 linq 获取结果为

[0] =  id = 1, title = "1-AAAA Depot", subs = System.Collections.Generic.List<<>f__AnonymousType10<string, string>> 
Subs

[0]  id = "1.1", title = "1.Retail"   <Anonymous Type>
[1]  id = "1.2", title = "1.Office"   <Anonymous Type>
[2]  id = "1.4", title = "1.Warehouse"    <Anonymous Type>

[1] =  id = 2, title = "2-BBBB Depot", subs = System.Collections.Generic.List<<>f__AnonymousType10<string, string>>     
Subs
[0]  id = "2.1", title = "2.Retail"   <Anonymous Type>
[1]  id = "2.2", title = "2.Office"   <Anonymous Type>
[2]  id = "2.3", title = "2.Field Staff"  <Anonymous Type>



[2] = id = 3, title = "4-CCCC Depot", subs = System.Collections.Generic.List<<>f__AnonymousType10<string, string>> 

Subs
[0]  id = "4.1", title = "4.Retail"   <Anonymous Type>

为此,我编写了如下所示的 linq,它适用于 .Net Core 2.1 但不适用于 3.1

**public JsonResult GetDepotDepartemntsForMap()
        
            dynamic mappingList = new List<DepotMapModel>();
            mappingList = _unitOfWork.Department.GetDepotWithDepartment();         
            return Json(mappingList);

        

 
    public class DepartmentMapModel
    
        public string id  get; set; 
        public string title  get; set; 
    

    public class DepotMapModel
    
        public string id  get; set; 
        public string title  get; set; 
        public List<DepartmentMapModel> subs  get; set; 
    
 
 public dynamic GetDepotWithDepartment()
        
            var list = goContext.goDepartmentWorkTime.
                GroupBy(d => new  d.DepotNo, d.Depot.DepotName )
            .Select(g => new
            
                id = g.Key.DepotNo,
                title = g.Key.DepotName,
                subs = g.Select(dd => new
                
                    id = dd.DepotNo + "." + dd.DepartmentID,
                    title = dd.Depot.DepotNo + "." + dd.Department.DepartmentName
                ).ToList()
            ).ToList();
            
            return list;
        **

【问题讨论】:

Stack Overflow 被这个 GroupBy 错误淹没了。不支持此形状。请查看其他问题。 【参考方案1】:

在新的 EF 核心版本中,它只允许在客户端上评估最后一次 Select() 调用。

可以通过调用goDepartmentWorkTime获取所有数据,所以不需要使用groupby,检查这个:

var list = (from d in _context.goDepartmentWorkTime                      
                     select new
                     
                         id = d.DepotNo,
                         title = d.Depot.DepotName,
                         subs =  new
                                
                                    id = d.DepotNo + "." + d.DepartmentID,
                                    title = d.Depot.DepotNo + "." + d.Department.DepartmentName
                                
                     ).ToList();

结果:

【讨论】:

以上是关于.NET Core 3.1 中的 Linq 表达式 GroupBy 错误的主要内容,如果未能解决你的问题,请参考以下文章

.Net Core Localization View:IViewLocalizer inside Linq 表达式

Linq 查询在 ASP.NET-Core 3.0 及更高版本中对数字等字符串进行排序

ASP.NET Core 和 Entity Framework Core:Linq 中的左(外)连接

ASP NET Core 中 HttpGet 中的分组依据

。NET Core 3.1-Ajax OnGet和使用NEW System.Text.Json返回对象

EF Core 3.1 (LINQ) - 如何在多列上左加入和分组