使用 linq 对列表中的记录进行分组

本文关键字:记录 linq 列表 使用 | 更新日期: 2023-09-27 18:30:56

我有一个记录列表,其中包含按周划分的工人工作时间,但以天为单位。

List<Hours> listHours = new List<Hours>();

我的班级在哪里:

public class Hours
{
    private int week;
    private DateTime day;
    private int idEmployee;
    private decimal amount;
    private int numberDay;
    public  DateTime Day
    { get { return day; } set { day = value; } }
    public int IdEmployee
    { get { return idEmployee; } set { idEmployee = value; } }
    public int Week
    { get { return week; } set { week = value; } }
    public decimal Amount
    { get { return amount; } set { amount = value; } }
}

我的列表小时数包含 4 条记录:

week     idemployee    day        numberday    amount
02        336        06/01/2014        1        8.5
02        336        07/01/2014        2        3.5
26        336        24/06/2014        2        8.5
26        336        25/06/2014        3        5.5

我需要按周和员工 ID 对小时数进行分组,并在所有工作日(如星期一、星期二)的相同记录显示金额中......周六和周日。例如,2014 年 1 月 6 日是星期一,因此应显示 8.5,否则应为零。

示例输出:

week      idEmployee        Mon    Tue    Wed    Thu    Fri    Sat    Sun
02          336             8.5    3.5     0       0      0      0    0
26          336              0     8.5    5.5      0      0      0    0

我需要下一个查询的 linq 中的等效项:

select week, idemployee , sum(amount for number day1),0,0,0,0,0,0
from myList
group by week, idemployee
union
select week, idemployee , 0,sum(amount for number day2),0,0,0,0,0
from myList
group by week, idemployee
union
...
union
select week, idemployee , 0,0,0,0,0,0,sum(amount for number day7)
from myList
group by week, idemployee

使用 linq 对列表中的记录进行分组

试试这个:-

涉及的步骤:-
1. 第一步很简单,因为我们需要按周和员工 ID
分组2.这有点棘手,由于星期几的范围为1-7,因此我使用Enumerable.Range使用列表并应用了左联接,因为即使没有数量,我们也需要所有工作日。

var result = items.GroupBy(x => new { x.Week, x.IdEmployee })
                  .Select(x => new
                           {
                              x.Key.Week,
                              x.Key.IdEmployee,
                              output = (from t in Enumerable.Range(1, 7)
                                        join w in x
                                        on t equals (int)w.Day.DayOfWeek into allitem
                                        from data in allitem.DefaultIfEmpty()
                                        select new 
                                        {
                                            Amount = data == null ? 0 : data.Amount
                                        }).ToList()
                          });

我使用以下作为输入的地方:-

 List<Hours> items = new List<Hours>
            {
                new Hours { Week = 2, IdEmployee=336,Day = new DateTime(2014,01,06),Amount = 8.5m },
                new Hours { Week = 2, IdEmployee=336,Day = new DateTime(2014,01,07),Amount = 3.5m },
                new Hours { Week = 26, IdEmployee=336,Day = new DateTime(2014,06,24),Amount = 8.5m },
                new Hours { Week = 26, IdEmployee=336,Day = new DateTime(2014,06,25),Amount = 5.5m }
            };

然后我只是使用以下命令在屏幕上打印输出:-

string[] days = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
            foreach (var item in result)
            {
                Console.WriteLine("Week:{0}'tEmployeeId:{1}", item.Week, item.IdEmployee);
                foreach (var x in item.output.Select((v,i) => new {v,i}))
                {
                    Console.WriteLine("{0}'t{1}",days[x.i],x.v.Amount);
                }
                Console.WriteLine();
            }