我正在创建可以使用各种分组显示的TreeView
。基本课程如下:
public class MachineStatus
{
public string MachineName {get;set;}
public string Department {get;set;}
public string LocationName {get;set;}
public IEnumerable<DeviceStatus> Devices {get;set;}
}
public class DeviceStatus
{
public string DeviceName {get;set;}
public string DeviceType {get;set;}
public string IpAddress {get;set;}
public ConnectionStatus Status {get;set;}
}
这些群组可以是Department
,Location
和DeviceType
。 Linq很容易前两个。但是,DeviceType
具有挑战性,因为每个Machine
可能包含多个具有不同类型的Device
个对象。
原始数据
Machine 1
|__ Device A (Type Foo)
|__ Device B (Type Bar)
Machine 2
|__ Device C (Type Foo)
|__ Device D (Type Zed)
结果
Type Bar
|__ Machine 1
|__Device B
Type Foo
|__Machine 1
|__Device A
|__Machine 2
|__Device C
Type Zed
|__Machine 2
|__Device D
我认为在尝试分组之前我必须将MachineStatus
记录列表展平,但我在使用SelectMany时感到困惑......
答案 0 :(得分:1)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TestConsoleApp
{
class Program
{
static void Main(string[] args) {
DeviceStatus deviceA = new DeviceStatus() { DeviceName = "A", DeviceType = "foo" };
DeviceStatus deviceB = new DeviceStatus() { DeviceName = "B", DeviceType = "bar" };
DeviceStatus deviceC = new DeviceStatus() { DeviceName = "C", DeviceType = "foo" };
DeviceStatus deviceD = new DeviceStatus() { DeviceName = "D", DeviceType = "zed" };
MachineStatus status1 = new MachineStatus() { MachineName = "1", Department = "1", LocationName = "1", Devices = new List<DeviceStatus>{ deviceA, deviceB} };
MachineStatus status2 = new MachineStatus() { MachineName = "2", Department = "2", LocationName = "2", Devices = new List<DeviceStatus> { deviceC, deviceD } };
List<MachineStatus> machines = new List<MachineStatus>() { status1, status2};
var result = machines.SelectMany(x => x.Devices, (a, b) => new { DeviceType = b.DeviceType, MachineName = a.MachineName, DeviceName = b.DeviceName } );
var result2 = result.GroupBy(x => new {x.DeviceType}).Select( z => new { DeviceType = z.Key.DeviceType, Machines = z.ToList().GroupBy(y => y.MachineName) });
foreach (var group1 in result2)
{
foreach (var group2 in group1.Machines)
{
foreach (var group3 in group2)
{
Console.Write(group1.DeviceType + ":");
Console.Write(group3.MachineName + ":");
Console.WriteLine(group3.DeviceName);
}
}
}
Console.ReadLine();
}
public class MachineStatus
{
public string MachineName { get; set; }
public string Department { get; set; }
public string LocationName { get; set; }
public IEnumerable<DeviceStatus> Devices { get; set; }
}
public class DeviceStatus
{
public string DeviceName { get; set; }
public string DeviceType { get; set; }
public string IpAddress { get; set; }
public ConnectionStatus Status { get; set; }
}
public class ConnectionStatus
{
}
}
}
产生以下输出:
FOO:1:甲
FOO:2:C
条:1:乙
zed:2:D
分组为:
FOO:1:甲
foo:2:C
吧:1:B
zed:2:D
答案 1 :(得分:1)
您可以使用SelectMany&amp; GroupBy是这样的: -
var result = machines.SelectMany(x => x.Devices,
(machineObj, devices) => new { machineObj, devices })
.GroupBy(x => new { x.devices.DeviceType, x.machineObj.Department,
x.machineObj.LocationName })
.Select(x => new
{
DeviceType = x.Key.DeviceType,
Department = x.Key.Department,
Location = x.Key.LocationName,
machines = x
});
以下是我用过的样本数据的完整Working Fiddle,以下是同样的输出。