Linq group by然后只得到其中一项

时间:2017-06-20 14:30:05

标签: c# linq group-by

我有以下课程,用于为员工分配任务。

public class TaskDetails
    {
        public int TaskGroupId { get; set; }
        public int TaskId { get; set; }
        public string AssignedTo { get; set; }
        public string TaskName { get; set; }

    }

通常我们会得到一个任务组列表,以及他们被分配到的人员如何,每个任务都分组在 TaskGroupId 下,每个任务组下的每个任务都有一个特定的taskid,谁负责为了它。

List<TaskDetails> tasks = new List<TaskDetails>
            {
                new TaskDetails
                {
                    AssignedTo = "JOHN",
                    TaskGroupId = 100,
                    TaskId = 1,
                    TaskName = "FA"
                },
                new TaskDetails
                {
                    AssignedTo = "TOM",
                    TaskGroupId = 100,
                    TaskId = 1,
                    TaskName = "FA"
                },
                new TaskDetails
                {
                    AssignedTo = "JOHN",
                    TaskGroupId = 100,
                    TaskId = 2,
                    TaskName = "GH"
                },
                new TaskDetails
                {
                    AssignedTo = "TOM",
                    TaskGroupId = 100,
                    TaskId = 2,
                    TaskName = "GH"
                },
                new TaskDetails
                {
                    AssignedTo = "JOHN",
                    TaskGroupId = 99,
                    TaskId = 1,
                    TaskName = "XY"
                },
                new TaskDetails
                {
                    AssignedTo = "TOM",
                    TaskGroupId = 99,
                    TaskId = 1,
                    TaskName = "XY"
                },
                new TaskDetails
                {
                    AssignedTo = "JOHN",
                    TaskGroupId = 99,
                    TaskId = 2,
                    TaskName = "YX"
                },
                new TaskDetails
                {
                    AssignedTo = "TOM",
                    TaskGroupId = 99,
                    TaskId = 2,
                    TaskName = "YX"
                }
            };

我要做的是按 TaskGroupId AssignedTo 对每项任务进行分组,但是如果将任务分配给多个人,我只需要检索一个他们回来了,在上面的例子中,任务1被分配给约翰和汤姆,但我只需要其中一个,无论哪一个(可能是汤姆或约翰)。我已经尝试了以下但是它检索了4个结果以及截图中看到的John和Tom。我可以从GroupBy语句中删除x.AssignedTo,它给出了2个结果,然后在TaskLegs部分重复任务,所以也没用。

enter image description here

 var result = tasks
   .GroupBy(x => new { 
      x.TaskGroupId, 
      x.AssignedTo })
   .Select(group => new { 
      GroupDetails = group.Key, 
      TaskLegs = group
        .OrderBy(x => x.TaskId)
        .ToList() })
   .ToList();

是否仍然以某种方式对结果进行分组,因此我只能从分组结果集中检索其中一个结果?基于上面的例子,我试图得到2个结果,一个用于任务组100,一个用于任务组99。

谢谢

2 个答案:

答案 0 :(得分:4)

如果您只需要每个TaskGroupId一个项目,那么您只能按该字段进行分组。按TaskGroupIdAssignedTo分组意味着您将为这两者的每个组合获得一个组,这就是您获得四个项目的原因。

所以你的查询必须开始:

tasks.GroupBy (x => x.TaskGroupId)

然后你有两个组(对于TaskGroupId 99和100)。

然后,您需要将数据选择为所需的表单。我对这些数据的形式有点不清楚。它应该只在每组下面有一项任务吗?  如果是这样的话:

.Select(group => new { TaskGroupId = group.Key, TaskLegs = group.OrderBy(x => x.TaskId).First() }).

如果它应该包含每个不同的任务,那么你需要做更多的分组:

.Select(group => new { 
    TaskGroupId  = group.Key, 
    TaskLegs = group
        .GroupBy(x=>x.TaskId)
        .Select(y => y.First())
        .OrderBy(y=>y.TaskId) 
})

这将为您提供两个项目,每个任务组一个。对于TaskIds 1和2,每个项目在TaskLegs中都有两个项目。

奖金思想:

如果要列出分配给任务的所有人员,可以将TaskLegs的定义更改为:

TaskLegs = group
    .GroupBy(x=>x.TaskId)
    .Select(y => new {
        TaskId = y.Key, 
        AssignedTo = y.Select(z => z.AssignedTo)
    })
    .OrderBy(y=>y.TaskId)

答案 1 :(得分:0)

试试这个..

var result = tasks.GroupBy(x => new x.TaskGroupId) .Select(group => new { GroupDetails = group.Key, TaskLegs = group.Take(1) }) .ToList();