LINQ合并导致行

时间:2009-11-24 14:04:40

标签: linq linq-to-sql merge grouping

我有一个LINQ查询,它返回一组行。结构是:

NAME,    col1, col2, col3, col4
name1     1    null  null  null
name1    null   1    null  null
name1    null  null   1     1 

结果我希望有一行包含

name1     1     1     1     1

所以我想按名称对这些结果进行分组,并将其他列合并(sum?),这样如果我在列的其中一行中没有null,我将收到除null之外的任何内容。

感谢您的帮助!

2 个答案:

答案 0 :(得分:4)

public class AggregateRows
{
    class AA { public string A, B, C, D;}

    public void DoIt()
    {
        List<AA> a = new List<AA>(  ) 
        {
            new AA { A="1", B=null, C=null, D=null},
            new AA { A=null, B="1", C=null, D=null},
            new AA { A=null, B=null, C="1", D=null},
            new AA { A=null, B=null, C=null, D="1"},
        };

        var result = a.Aggregate( ( a1, a2 ) => new AA { A = a1.A ?? a2.A, B = a1.B ?? a2.B, C = a1.C ?? a2.C, D = a1.D ?? a2.D } );
        Console.WriteLine("{0}{1}{2}{3}",result.A,result.B,result.C,result.D);
    }
}

产量

1111

public class AggregateRows
{
    class AA
    {
        public string N, A, B, C, D;
    }

    public void DoIt()
    {
        List<AA> data = new List<AA>() 
        {
            new AA { N="Name", A="1", B=null, C=null, D=null},
            new AA { N="Name", A=null, B="2", C=null, D=null},
            new AA { N="Name", A=null, B=null, C="3", D=null},
            new AA { N="Name", A=null, B=null, C=null, D="4"},
            new AA { N="Name2", A="2", B=null, C=null, D=null},
            new AA { N="Name2", A=null, B="2", C=null, D=null},
            new AA { N="Name2", A=null, B=null, C="2", D=null},
            new AA { N="Name2", A=null, B=null, C=null, D="2"},
        };

        var results = data.GroupBy( a => a.N )
            .Select( k =>
            {
                var values = k.Aggregate( ( a1, a2 ) => new AA
                {
                    A = a1.A ?? a2.A,
                    B = a1.B ?? a2.B,
                    C = a1.C ?? a2.C,
                    D = a1.D ?? a2.D
                } );
                return new AA { N = k.Key, A = values.A, B = values.B, C = values.C, D = values.D };
            } );
        foreach ( var result in results )
            Console.WriteLine( "{0} {1}{2}{3}{4}", result.N, result.A, result.B, result.C, result.D );
    }
}

产量

Name 1234
Name2 2222

编辑:回应你的澄清......

我想你可以从这里拿走它。如果你想要做的只是找出组内是否有列,那么像布鲁诺的回答中的Any运算符就是要走的路。 Aggregate只有在您尝试实际访问所有值时才需要执行更复杂的操作,例如对它们进行求和(尽管Jon强调,Sum处理该特定情况)。

简而言之,您想要的是在答案中进行分组,然后在组中使用Aggregate逐行合并或Any合并{{1取决于你的上下文中哪个更清楚(如果你在每个组中有大量数据,则更有效)

答案 1 :(得分:3)

class MyObj
{
    public string Name { get; set; }
    public int? Col1 { get; set; }
    public int? Col2 { get; set; }
    public int? Col3 { get; set; }
    public int? Col4 { get; set; }
}

List<MyObj> l = new List<MyObj> {
    new MyObj {Name = "name1", Col1 = 1 },
    new MyObj {Name = "name1", Col2 = 1 },
    new MyObj {Name = "name1", Col3 = 1 },
    new MyObj {Name = "name1", Col4 = 1 }
};

var qry = from o in l
          group o by o.Name into g
          select new
          {
              Name = g.Key,
              Col1 = g.Any(e => e.Col1.HasValue) ? (int?)1 : null,
              Col2 = g.Any(e => e.Col2.HasValue) ? (int?)1 : null,
              Col3 = g.Any(e => e.Col3.HasValue) ? (int?)1 : null,
              Col4 = g.Any(e => e.Col4.HasValue) ? (int?)1 : null
          };