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

时间:2014-11-18 16:52:32

标签: c# linq

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

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

}

我的listHours包含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

1 个答案:

答案 0 :(得分:1)

试试这个: -

所涉及的步骤: -
1.第一步很简单,因为我们需要按周和分组进行分组。雇员
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();
            }