【问题标题】:Linq query to group by based on special conditionLinq查询根据特殊条件分组
【发布时间】:2019-01-22 13:41:07
【问题描述】:

我的桌子是:

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

我已尝试以下查询

  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 的结果。

【问题讨论】:

  • @HimBromBeere 请检查我尝试过的查询

标签: c# .net linq


【解决方案1】:

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

要求 1:忽略 id

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);

【讨论】:

    【解决方案2】:
    public class test
        {
            public int id { get; set; }
            public int globalId { get; set; }
            public string taskStatus { get; set; }
        }
    
        public void SampleName()
        {
            List<test> testList = new List<test>()
            {
                new test() { id = 1, globalId =  10, taskStatus =  "New"},
                new test() { id = 2 , globalId = 11 , taskStatus = "New"},
                new test() { id = 3 , globalId = 10 , taskStatus = "InProgress"},
                new test() { id = 4 , globalId = 12 , taskStatus = "New"}
            };
    
            var result = testList.Where(q => testList.Count(a => a.globalId == q.globalId) == 1 && q.taskStatus != "InProgress" && q.id < 4).ToList();
        }
    

    【讨论】:

    • 代码转储通常会导致错误的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-19
    • 1970-01-01
    • 1970-01-01
    • 2012-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多