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

.NET Core 5.0 Linq GroupBy查询报错及分组查询实现需求

问题解决:Linq GroupBy在EF Core 5.0中的类型不匹配错误

错误原因

你在EF Core查询的投影阶段(构造ReservationViewModel时),对Service字段的子查询先调用了.ToList(),紧接着执行.GroupBy()。此时EF Core会尝试将GroupBy操作翻译成数据库查询,但.ToList()已经将子查询结果转换成了内存集合List<AdminReservationviewModel>,而EF的GroupBy方法要求参数是IQueryable<T>类型,因此抛出类型不匹配的错误。

解决方案

将分组操作放到内存中执行,先把所需的基础数据加载到内存,再进行分组和ViewModel构造,避免EF尝试翻译内存集合上的查询操作。

修改后的Controller代码

// 1. 加载主预订数据到内存
var baseReservations = (from reservation in c_.Reservations
                        join times in c_.Times on reservation.TimeId equals times.TimeId
                        join users in c_.Users on reservation.EmployerId equals users.UserId
                        orderby reservation.Date
                        select new
                        {
                            reservation.MeetingId,
                            users.UserName,
                            reservation.Date,
                            times.TimeName,
                            reservation.ToplamSure,
                            reservation.ToplamTutar
                        }).ToList();

// 2. 加载所有关联的服务数据到内存
var relatedServices = (from m in c_.MultiReservations
                       join s in c_.Services on m.ServiceId equals s.ServiceId
                       select new
                       {
                           m.MeetingId,
                           m.ServiceId,
                           s.Operation
                       }).ToList();

// 3. 构造最终ViewModel并在内存中分组
var t = baseReservations.Select(res => new ReservationViewModel
{
    MeetingId = res.MeetingId,
    UserName = res.UserName,
    Date = res.Date,
    Time = res.TimeName,
    ToplamSure = res.ToplamSure,
    ToplamTutar = res.ToplamTutar,
    Service = relatedServices
        .Where(s => s.MeetingId == res.MeetingId)
        .Select(s => new AdminReservationviewModel
        {
            ServiceId = s.ServiceId,
            Operations = s.Operation
        })
        .GroupBy(s => s.ServiceId)
        .ToList()
}).ToList();

可选优化:合并同ServiceId的操作名称

如果同一个ServiceId对应多个操作,你可以用string.Join合并操作名称,修改Service字段的构造代码:

Service = relatedServices
    .Where(s => s.MeetingId == res.MeetingId)
    .GroupBy(s => s.ServiceId)
    .Select(grp => new AdminReservationviewModel
    {
        ServiceId = grp.Key,
        Operations = string.Join("、", grp.Select(s => s.Operation))
    })
    .GroupBy(s => s.ServiceId)
    .ToList()

关键说明

  • 先调用.ToList()将EF查询结果加载到内存,后续的GroupBy、Select等操作就会在内存中执行,避免EF尝试翻译不支持的操作组合。
  • 这种方式会两次查询数据库(主预订数据和关联服务数据),如果数据量不大,性能影响可以忽略;如果数据量较大,可考虑使用Include/ThenInclude预加载关联数据,但仍需注意在内存中处理分组。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 04:10:15