首页 > 解决方案 > Linq查询根据特殊条件分组

问题描述

我的桌子是:

id | globalId | taskStatus |
1  | 10       | New        | 
2  | 11       | New        |
3  | 10       | InProgress |
4  | 12       | New        |

我想要一个 linq 查询,它返回第 2 行的结果。

签入查询条件

  1. 如果任何记录的任务状态为 InProgress,想要忽略那些具有相同 globalId 的记录。因此,在这种情况下,记录为 1、3 具有相同的全局 ID 10,但 ID 为 3 的记录的任务状态为 InProgress,因此不需要两条记录中的任何一条。
  2. 还要检查条件 ID < 4

我尝试了以下查询

  var result = (from meetings in db.Meetings
                      join taskStatus in db.TaskStatus on meeting.TaskStatusId equals taskStatus.TaskStatusId
                      where (taskStatus.Name == InternalTaskStatus.New || taskStatus.Name == InternalTaskStatus.ToBePlannedInFuture || taskStatus.Name == InternalTaskStatus.Failed)
                      && meeting.CalendarEvent != CalendarEvents.Delete
                      && meeting.StartDateTime >= planningPeriodStartDate && meeting.EndDateTime <= planningPeriodEndDate
                      group meeting by meeting.GlobalAppointmentId  into m
                      select new
                      {
                          MeetingResult = m.FirstOrDefault()
                      }).FirstOrDefault();

在上面的查询中,我添加了任务状态检查,只需要带有 taskStatus-New、Failed、ToBePlannedInFuture 的记录。但是在这种情况下,根据上表,我得到了错误的结果,我得到了 id 为 1 的结果。

标签: c#.netlinq

解决方案


解决这个问题的理想方法是拆分需求。

要求 1:忽略 id < 4 的项目

var step1 = testList.Where(x=>x.id<4);

在此处输入图像描述

要求2:忽略具有相同globalId的项目组相同,并且组中的任何元素都没有处于“InProgress”状态

var step2 = step1.GroupBy(x=>x.globalId)
            .Where(x=>!x.Any(c=>c.taskStatus.Equals("InProgress")));

在此处输入图像描述

现在您需要将组展平以获得 IEnumerabble 的结果

var step3= step2.SelectMany(x=>x);

在此处输入图像描述

把它们放在一起

var result = testList.Where(x=>x.id<4).GroupBy(x=>x.globalId)
            .Where(x=>!x.Any(c=>c.taskStatus.Equals("InProgress")))
            .SelectMany(x=>x);

推荐阅读