Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Linq GroupBy包含空键_C#_Sql_Linq - Fatal编程技术网

C# Linq GroupBy包含空键

C# Linq GroupBy包含空键,c#,sql,linq,C#,Sql,Linq,我有一些层次结构的元素。我想对这些元素进行分组 cuttingTools = machines.SelectMany(x0 => x0.Operations) .SelectMany(x1 => x1.Tools) .SelectMany(x2 => x2.CuttingTools) .GroupBy(x => x.Tool.Opera

我有一些层次结构的元素。我想对这些元素进行分组

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>>;

但目前,M3不会出现在结果中。即使M3没有元素,我也如何包含它。

我认为您需要为空元素创建一些空占位符值。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=

虽然
groupby
至少会列出所有的组键,但某些组的元素可能为空,但键应该列在组中。我不确定这在Lambda中是否可行。我有一个LINQ表达式可以工作,也就是说,如果我正确理解了您的数据结构,如果您想看到它?谢谢。Alexander@AllyThanks的回答中提到了正确的解决方案。通过添加DefaultIfEmpty的左连接解决了我的问题。
A=T1
B=
C=