使用Linq扩展方法创建嵌套分组

本文关键字:嵌套 创建 方法 Linq 扩展 使用 | 更新日期: 2023-09-27 17:51:20

我正在构建一个具有日记功能的应用程序,并且在该对象中有一个约会列表。为了显示,我需要创建一个嵌套的分组,格式如下

Heading 1
 Sub-heading 1
   Data row 1
   Data row 2
Sub-heading 2
  Data row 1
  Data row 2
Heading 2
 Sub-heading 1
  Data row 1
  Data row 2

标题是约会所在的办公室,子标题是约会所在的房间。在查看以下模型时,这将更有意义;

public class Diary
{
    public int Id {get; set; }
    public DateTime DiaryDate {get; set; }
    List<Appointment> Appointments {get; set;}
}
public class Appointment
{
    public int Id {get; set;}
    public int DiaryId {get; set;}
    public DateTime StartTime {get; set;}
    public DateTime EndTime {get; set; }
    public string Attendees {get; set; }
    public Office Office {get; set; }
    public Room Room {get; set; }
}

Office是一个带办公位置的enum, Room也是一个带房间的enum。

目前我已经用下面的代码解决了这个问题:

Appointments.GroupBy(k => k.Office, k => k)
            .ToDictionary(k => k.Key,
                          k => k.ToList().GroupBy(sk => sk.Room)
                                         .ToDictionary(mk => mk.Key, mk => mk.ToList()));

我正在给视图模型写日记,其中约会类型为

public Dictionary<Office, Dictionary<Room, List<Appointment>>> Appointments { get; set; }

本质上,我的长group by语句是通过Office对数据分组,然后使用resultSelector过载来投影原始对象。然后,我将IGrouping结果转换为Dictionary,其中键是办公室,值是Appointment类型的列表。然后,我将Appointment类型的每个列表按Room分组,在字典中创建一个字典,该字典产生具有密钥Office的类型Dictionary,然后具有密钥Room的字典和Appointment列表作为每个键的值。

这段代码产生了期望的结果,但我认为它很难阅读,在循环时在视图中更难以理解,而且可能相当低效。

有没有人能给我一些建议,告诉我如何才能简单地达到我想要的结果?

使用Linq扩展方法创建嵌套分组

您实际上正在构建一个查找,一个每个键具有多个值的字典。就用它吧

你的查询变成:

var query = appointments.OrderBy(a => a.Office).ThenBy(a => a.Room)
    .GroupBy(a => a.Office)
    .ToDictionary(g => g.Key, g => g.ToLookup(a => a.Room));