C# Linq 父子展平

C# Linq Parent Child flatten

我有一个像下面这样的对象:

List<classA> obj = new List<classA>() {
new classA() { vCode = "100", sCode = "PB", regional = "A",  new List<classB>() {
        new classB() { amount = 100, aCode = "A100", status = 1 },
        new classB() { amount = 110, aCode = "A200", status = 1 },
        new classB() { amount = 150, aCode = "A300", status = 1 }
    }
},
new classA() { vCode = "101", sCode = "KB", regional = "A",  new List<classB>() {
        new classB() { amount = 500, aCode = "A100", status = 1 },
        new classB() { amount = 610, aCode = "A200", status = 1 },
        new classB() { amount = 750, aCode = "A300", status = 1 }
    }
},
new classA() { vCode = "102", sCode = "PB", regional = "A",  new List<classB>() {
        new classB() { amount = 100, aCode = "A100", status = 1 },
        new classB() { amount = 110, aCode = "A100", status = 1 },
        new classB() { amount = 150, aCode = "A200", status = 1 }
    }
}

}

如何展平结果如下:

list of Anonymous =>  
   { vcode = "100", sCode = "PB", regional = "A", amount = 100, aCode = "A100", status = 1 },
   { vCode = "100", sCode = "PB", regional = "A", amount = 110, aCode = "A200", status = 1 },
   { vCode = "100", sCode = "PB", regional = "A", amount = 150, aCode = "A300", status = 1 },
   { vCode = "101", sCode = "KB", regional = "A", amount = 500, aCode = "A100", status = 1 },
   { vCode = "101", sCode = "KB", regional = "A", amount = 610, aCode = "A200", status = 1 },
   { vCode = "101", sCode = "KB", regional = "A", amount = 750, aCode = "A300", status = 1 },
   { vCode = "102", sCode = "PB", regional = "A", amount = 100, aCode = "A100", status = 1 },
   { vCode = "102", sCode = "PB", regional = "A", amount = 110, aCode = "A100", status = 1 },
   { vCode = "102", sCode = "PB", regional = "A", amount = 150, aCode = "A200", status = 1 }

有人可以帮帮我吗?

你会用SelectMany

Projects each element of a sequence to an IEnumerable<T> and flattens the resulting sequences into one sequence.

给定

List<classA> obj = new List<classA>()
{
   new classA()
   {
      vCode = "100", sCode = "PB", regional = "A", List = new List<classB>()
      {
         new classB() {amount = 100, aCode = "A100", status = 1},
         new classB() {amount = 110, aCode = "A200", status = 1},
         new classB() {amount = 150, aCode = "A300", status = 1}
      }
   },
   new classA()
   {
      vCode = "101", sCode = "KB", regional = "A", List = new List<classB>()
      {
         new classB() {amount = 500, aCode = "A100", status = 1},
         new classB() {amount = 610, aCode = "A200", status = 1},
         new classB() {amount = 750, aCode = "A300", status = 1}
      }
   },
   new classA()
   {
      vCode = "102", sCode = "PB", regional = "A", List = new List<classB>()
      {
         new classB() {amount = 100, aCode = "A100", status = 1},
         new classB() {amount = 110, aCode = "A100", status = 1},
         new classB() {amount = 150, aCode = "A200", status = 1}
      }
   }
};

例子

var results = obj.SelectMany(x =>
   x.List.Select(y => new
   {
      x.vCode,
      x.sCode,
      x.regional,
      y.amount,
      y.aCode,
      y.status
   }));

此示例使用 匿名类型,但是您可以轻松地将其替换为具体 class

给定

internal class ClassC
{
   public string vCode { get; set; }
   public string sCode { get; set; }
   public string regional { get; set; }
   public int amount { get; set; }
   public string aCode { get; set; }
   public int status { get; set; }
}

例子

var results = obj.SelectMany(x =>
   x.List.Select(y => new ClassC
   {
      vCode =x.vCode,
      sCode = x.sCode,
      regional = x.regional,
      amount = y.amount,
      aCode = y.aCode,
      status = y.status
   }));

您可以使用 .ForEach() 函数和 .Select() 函数 return 一个包含 类.

两者内容的新对象
    List<NewModel> newList = new List<NewModel>();
    obj.ForEach(d =>
        {
            var temp = d.data.Select(s => new NewModel()
            {
                vCode = d.vCode,
                sCode = d.sCode,
                regional = d.regional,
                aCode = s.aCode,
                amount = s.amount,
                status = s.status
            });
        }
    );