2009-11-24 3 views
2

행 집합을 반환하는 LINQ 쿼리가 있습니다. 구조는 : 나는LINQ 병합 결과가 행으로 표시됩니다.

name1  1  1  1  1 

를 포함하는 하나 개의 행이 원하는 결과

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

그래서 그룹 이름으로 그 결과를 원하고 (? 합)을 병합 다른 열이 나는 경우 이렇게 열의 행 중 하나에서 null이 아님 - null을 제외한 아무 것도받지 않습니다.

도움 주셔서 감사합니다.

+2

실제로 합계를 원하십니까? null 값 중 하나가 실제로 2 인 경우 결과를 원하겠습니까? –

+0

당신이 물건을 그룹화하는 방법을 보여주기 위해 더 나은 샘플 데이터를 제공해야합니다. –

+0

마지막 구문에서 "null을 제외한 모든 것"에서 언급했듯이 나는 어떤 종류의 참 또는 거짓 값을 필요로합니다. 내 경우에는 null이 거짓이고 다른 것은 사실 일 것이다. –

답변

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 
      }; 
+0

+1 : Nice and 간결한 광산! –

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 

편집을 산출 산출 : ... 당신의 해명에 대응

당신이 여기에서 그것을 가져갈 수있을 것 같아요. 그룹 내에 열이 있는지 여부를 확인하려면 브루노 (Bruno)의 대답과 같은 Any 연산자가 필요합니다. Aggregate은 실제로 합계와 같이 더 복잡한 작업을 수행하기 위해 모든 값을 실제로 방문하려는 경우에만 필요합니다 (Jon이 언급했듯이 Sum이 해당 사례를 처리 함). 당신이 대답은 모두 같은 그룹화되고 싶어하고 그룹 내에서 당신이 중 하나를 (에 따라하는 것은 당신의 맥락에서 명확하다 GroupBy의 결과에 행 또는 여러 Any에 의해 행을 병합 Aggregate를 사용하는 것을 한마디로

, 각 그룹 내에서 많은 양의 데이터가있는 경우보다 효율적입니다.)

+0

당신이 의미하는 바를 Console.WriteLine ("{0} {1} {2} {3} {4}", result.N, result.A, result.B, result.C, result.D); –

+0

@ melco-man : 네, 고마워요. (실제로 다른 곳에서 올바른 코드를 가지고 있었지만, 평행선에 대한 변경 사항을 편집하고 있었고 편집자는 긴 게시물에서이를 수행하는 데 도움이되지 않았습니다!) –

관련 문제