2013-11-24 56 views
2

我有一些層次結構的元素。這些元素我想分組。Linq GroupBy包含空鍵

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

我雖然'組by'將至少列表中的所有組密鑰,一些組的元素可以** **空,但** **的關鍵應該是列在小組中。 –

+0

我不確定這是否適用於Lambda。我有一個可以工作的LINQ表達式,也就是說,如果我正確地理解了您的數據結構,是否希望看到它? – Ally

+0

謝謝。在Alexander @Ally –

回答

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= 
+0

的答案中提到了正確的解決方案。謝謝。通過添加DefaultIfEmpty來解決我的問題。 –