C# LINQ 嵌套“条件/复合”分组

5

我希望你能帮助我编写一个LINQ查询,其中我尝试进行一些“条件/复合”分组。(不确定这是否是正确的术语)。让我解释一下。

如果我有以下类:

class Device
{
    int Id;
    string DeviceType;
    string DeeviceValue;
}

class Employee
{
    int Id;
    int SupervisorId;
    int CountryId;
    List<Device> Devices = new List<Device>();
}

假设我有以下对象:

List<Employee> Employees = new List<Employee>();
var emp1 = new Employee();
emp1.Id = 1;
emp1.CountryId = 1;
emp1.SupervisorId = 1;
Device dev1 = new Device();
dev1.Id = 1;
dev1.DeviceType = "Desk Phone";
dev1.DeviceValue = "132456789";
emp1.Devices.Add(dev1);
Employees.Add(emp1);

var emp2 = new Employee();
emp2.Id = 2;
emp2.CountryId = 1;
emp2.SupervisorId = 1;
Device dev2 = new Device();
dev2.Id = 2;
dev2.DeviceType = "Desk Phone";
dev2.DeviceValue = "123456789";
emp2.Devices.Add(dev2);
Device dev6 = new Device();
dev6.Id = 6;
dev6.DeviceType = "Conference Phone";
dev6.DeviceValue = "123456789";
emp2.Devices.Add(dev6);
Employees.Add(emp2);

var emp3 = new Employee();
emp3.Id = 3;
emp3.CountryId = 2;
emp3.SupervisorId = 1;
Device dev3 = new Device();
dev3.Id = 3;
dev3.DeviceType = "Desk Phone";
dev3.DeviceValue = "456789123";
emp3.Devices.Add(dev3);
Employees.Add(emp3);

var emp4 = new Employee();
emp4.Id = 4;
emp4.CountryId = 2;
emp4.SupervisorId = 4;
Device dev4 = new Device();
dev4.Id = 4;
dev4.DeviceType = "Desk Phone";
dev4.DeviceValue = "987123456";
emp4.Devices.Add(dev4);
Device dev5 = new Device();
dev5.Id = 5;
dev5.DeviceType = "Dealerboard";
dev5.DeviceValue = "987123456";
emp4.Devices.Add(dev5);
Employees.Add(emp4);

我想创建一个按照监管者ID -> 国家ID -> 设备类型进行分组的查询。这很好,我有以下查询,可以给我想要的结果。

var result = Employees.SelectMany(e => e.Devices, (employee, devices) => new { employee, devices })
.GroupBy(e => new { e.devices.DeviceType, e.employee.SupervisorId, e.employee.CountryId })
.Select(e => new
    {
        DeviceType = e.Key.DeviceType,
        Supervisor = e.Key.SupervisorId,
        Country = e.Key.CountryId,
        employees = e
    });

我遇到的问题是,我想创建一个DeviceType组,可以包含多个设备类型,如“桌面电话”和“会议电话”,而不是为每种设备类型单独创建一个组。
编辑-为了完整性
上述查询给我以下结果
1. 设备类型 -> 桌面电话 监管员ID -> 1 国家ID -> 1 员工 -> 这将是Id = 1和Id = 2的员工
2. 设备类型 -> 会议电话 监管员ID -> 1 国家ID -> 1 员工 -> 这将是Id = 2的员工
3. 设备类型 -> 桌面电话 监管员ID -> 1 国家ID -> 2 员工 -> 这将是Id = 3的员工
4. 设备类型 -> 桌面电话 监管员ID -> 4 国家ID -> 2 员工 -> 这将是Id = 4的员工
5. 设备类型 -> Dealerboard 监管员ID -> 4 国家ID -> 2 员工 -> 这将是Id = 4的员工
我需要的结果是:
1. 设备类型 -> 桌面电话和会议电话 监管员ID -> 1 国家ID -> 1 员工 -> 这将是Id = 1和Id = 2的员工
2. 设备类型 -> 桌面电话 监管员ID -> 1 国家ID -> 2 员工 -> 这将是Id = 3的员工
3. 设备类型 -> 桌面电话 监管员ID -> 4 国家ID -> 2 员工 -> 这将是Id = 4的员工
4. 设备类型 -> Dealerboard 监管员ID -> 4 国家ID -> 2 员工 -> 这将是Id = 4的员工
有没有一种方法可以通过LINQ并修改我已有的查询来实现这一点?
非常感谢任何帮助。
Pete

2
10/10 对于可重现的样本 - 包括设置数据!你获得了金星! - Jamiec
1
现在如果我能弄清楚你实际想要做什么就好了...你能具体说明一下你想要的结果是什么吗? - Jamiec
@Jamie,我更新了问题,希望更加清晰明了。 - Pete
1个回答

2
创建一个字典,键为每个设备类型,值为它们所属的组,然后在分组时使用该字典。请保留HTML标签。
var deviceGroup = new Dictionary<string, string>() { { "Desk Phone", "Phone" }, { "Conference Phone", "Phone" } };

var result = Employees.SelectMany(e => e.Devices, (employee, devices) => new { employee, devices })
            .GroupBy(e => new { 
DeviceGroup = deviceGroup.ContainsKey(e.devices.DeviceType) ? 
              deviceGroup[e.devices.DeviceType] 
              : e.devices.DeviceType, 
e.employee.SupervisorId, e.employee.CountryId })
.Select(e => new
{
DeviceGroup = e.Key.DeviceGroup,

Supervisor = e.Key.SupervisorId,
Country = e.Key.CountryId,
employees = e
});

谢谢@Martheen,这正是我想要的。 - Pete
这对我的情况来说是一个很好的解决方案,因为分组的映射可以由最终用户进行配置。创建字典给了我所有我需要的灵活性。再次感谢。 - Pete

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接