LINQ合并2个查询结果

LINQ merge 2 query results

数据表有 5 列

Name   Class   Course    Month    Score
Alex   C1      Math      12       90
Bob    C1      Chem      11       91
Alex   C2      Math      11       91
Alex   C1      Math      11       89
Bob    C1      Chem      12       97
Alex   C1      Math      10       94
Alex   C2      Chem      12       92
Bob    C2      Math      12       94

我想分组 (name, class) 并获取 11 月和 12 月的最高数学分数,以及最高化学分数。这是我的查询代码

DataRow[] dr1 = dt.Select("Course = 'Math' AND Month > 10");
var result_one = dr1.AsEnumerable()
    .GroupBy(r => new { Name = r.Field<string>("Name"), Class = r.Field<string>("Class") })
    .Select(g => new
    {
        Name = g.Key.Name, 
        Class = g.Key.Class, 
        Max = g.Max(r => r.Field<int>("Score")),
        Max_Month = g.FirstOrDefault(gg => gg.Field<int>("Score") == g.Max(r => r.Field<int>("Score"))).Field<int>("Month"),
    }
    ).Distinct().ToList();


DataRow[] dr2 = dt.Select("Course = 'Chem'");
var result_two = dr2.AsEnumerable()
    .GroupBy(r => new { Name = r.Field<string>("Name"), Class = r.Field<string>("Class") })
    .Select(g => new
    {
        Name = g.Key.Name,
        Class = g.Key.Class,
        Max = g.Max(r => r.Field<int>("Score")),
        Max_Month = g.FirstOrDefault(gg => gg.Field<int>("Score") == g.Max(r => r.Field<int>("Score"))).Field<int>("Month"),
    }
    ).Distinct().ToList();

我可以这样输出这 2 个查询结果:

Name  Class    Math_Max_Month    Math_Max
Alex   C1      12                90
Alex   C2      11                91
Bob    C2      12                94
Name  Class    Chem_Max_Month    Chem_Max
Bob    C1      12                97
Alex   C2      12                92

但是我怎样才能将这 2 个结果合并为 1 个输出,如下所示:

Name  Class    Math_Max_Month    Math_Max  Chem_Max_Month   Chem_Max
Alex   C1      12                90        null             null
Alex   C2      11                91        12               92
Bob    C1      null              null      12               97
Bob    C2      12                94        null             null

我试过使用 result_one.Concat(result_two)result_one.Union(result_two),但两者都不正确。

好吧,你的例子看起来有点复杂。所以我会在 int[] 而不是 DataRow[]

上给你答案
int[] first = new int[] { 3, 5, 6, 9, 12, 14, 18, 20, 25, 28 };
  int[] second = new int[] { 30, 32, 34, 36, 38, 40, 42, 44, 46, 48 };

  int[] result = first
    .Concat(second)
    .OrderBy(x => x)
    .ToArray();

输出将是

// 3, 5, 6, 9, 12, 14, 18, 20, 25, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48
  Console.Write(String.Join(", ", result));

理论上这应该适用于您的情况,感觉我们只处理数组。

这非常适合您的代码。,

DataRow[] dr1 = dtt.Select("Course = 'Math' AND Month > 10");
        var result_one = dr1.AsEnumerable()
            .GroupBy(r => new { Name = r.Field<string>("Name"), Class = r.Field<string>("Class") })
            .Select(g => new
            {
                Name = g.Key.Name,
                Class = g.Key.Class,
                Max = g.Max(r => r.Field<int>("Score")),
                Max_Month = g.FirstOrDefault(gg => gg.Field<int>("Score") == g.Max(r => r.Field<int>("Score"))).Field<int>("Month"),
            }
            ).Distinct().ToList();


DataRow[] dr2 = dtt.Select("Course = 'Chem'");
        var result_two = dr2.AsEnumerable()
            .GroupBy(r => new { Name = r.Field<string>("Name"), Class = r.Field<string>("Class") })
            .Select(g => new
            {
                Name = g.Key.Name,
                Class = g.Key.Class,                    
                Chem_Max = g.Max(r => r.Field<int>("Score")),
                Chem_Max_Month = g.FirstOrDefault(gg => gg.Field<int>("Score") == g.Max(r => r.Field<int>("Score"))).Field<int>("Month"),
            }
            ).Distinct().ToList();

左加入...

var lstLeftJoin = (from a in result_one
                           join b in result_two
                           on new { a.Name, a.Class } equals new { b.Name, b.Class }
                           into gj
                           from subpet in gj.DefaultIfEmpty()
                           select new { a.Name, a.Class, Math_Max_Month = a.Max_Month, Math_Max = a.Max, Chem_Max_Month = (subpet == null ? 0 : subpet.Chem_Max_Month), Chem_Max = (subpet == null ? 0 : subpet.Chem_Max) }).ToList();

正确加入...

  var lstRightJoin = (from a in result_two
                            join b in result_one
                            on new { a.Name, a.Class } equals new { b.Name, b.Class }
                            into gj
                            from subpet in gj.DefaultIfEmpty()
                            select new { a.Name, a.Class, Math_Max_Month = (subpet == null ? 0 : subpet.Max_Month), Math_Max = (subpet == null ? 0 : subpet.Max), a.Chem_Max_Month, a.Chem_Max }).ToList();

终于联盟...

var lstUnion = lstLeftJoin.Select(s => new { Name = s.Name, Class = s.Class, Math_Max_Month = s.Math_Max_Month, Math_Max = s.Math_Max, Chem_Max_Month = s.Chem_Max_Month, Chem_Max = s.Chem_Max }).Union(lstRightJoin.Select(s => new { Name = s.Name, Class = s.Class, Math_Max_Month = s.Math_Max_Month, Math_Max = s.Math_Max, Chem_Max_Month = s.Chem_Max_Month, Chem_Max = s.Chem_Max })).OrderBy(o => o.Name).ThenBy(c => c.Class).ToList();

结果

Name  Class    Math_Max_Month    Math_Max  Chem_Max_Month   Chem_Max
Alex   C1      12                90        null             null
Alex   C2      11                91        12               92
Bob    C1      null              null      12               97
Bob    C2      12                94        null             null