我有一些层次结构的元素。我想要分组这些元素。
cuttingTools = machines.SelectMany(x0 => x0.Operations)
.SelectMany(x1 => x1.Tools)
.SelectMany(x2 => x2.CuttingTools)
.GroupBy(x => x.Tool.Operation.Machine) as IQueryable<IGrouping<T, CuttingTool>>;
但我有一个大问题。如果机器没有任何子操作,工具或切割工具,则结果不包含空组。例如:
Machine Tool
M1 T1
M1 T2
M1 T3
M2 T1
M2 T2
M3 Null
M1 [T1, T2, T3]
M2 [T1, T2]
M3 [None]
但目前,M3不会出现在结果中。即使没有元素,我怎么能包括M3。
答案 0 :(得分:1)
我相信您需要为空元素创建一些空的占位符值。 DefaultIfEmpty可以做到这一点。请注意,在下面的示例中,我直接由父机器分组,而无需访问工具内部属性(在您的情况下为x.Tool.Operation.Machine)。如果在您的方案中无法做到这一点 - 您需要以某种方式动态创建和初始化默认值,并引用父级。
using System;
using System.Linq;
class Machine
{
public string MachineName;
public Operation[] Operations;
}
class Operation
{
public string OperationName;
public Tool[] Tools;
}
class Tool
{
public string ToolName;
public Tool(string name) { ToolName = name; }
}
class App
{
static void Main()
{
var machines = new[]
{
new Machine {
MachineName = "A", Operations = new[] { new Operation { OperationName = "O1", Tools = new[] { new Tool("T1") } } }
},
new Machine {
MachineName = "B", Operations = new[] { new Operation { OperationName = "O3", Tools = new Tool[0] } }
},
new Machine {
MachineName = "C", Operations = new Operation[0]
}
};
var defaultOp = new Operation() { Tools = new Tool[0] };
var defaultTool = new Tool("");
var res =
from m in machines
from o in m.Operations.DefaultIfEmpty(defaultOp)
from t in o.Tools.DefaultIfEmpty(defaultTool)
group t by m.MachineName;
foreach(var g in res)
{
Console.WriteLine(g.Key + "=" + string.Join(";", g.Select(x => x.ToolName)));
}
}
}
输出:
A=T1
B=
C=