2013-08-27 1 views
1

여러 열이있는 DataTable이 있습니다. 특정 열의 값이 반복되는 경우 해당 열을 제거하고 이에 대한 수량을 추가해야합니다. 예를 들어,DataTable에서 동일한 열 값을 가진 행을 제거하고 해당 값을 추가하십시오.

ITEM QTY 
------------ 
1  20 
2  10 
2  10 
3  20 

이 될 것 DataTable을 다음

ITEM QTY 
----------- 
1  20 
2  20 
3  20 

이 내가

var table = dt.AsEnumerable() 
.GroupBy(row => row.Field("ITEM")) 
.Select(group => group.First()) 
.CopyToDataTable(); 

그것은 여분의 행을 제거하지만 수량을 추가하지 않습니다했던 것입니다. 그러니 제발 도와주세요.

+0

은 [여기에 입력 링크 설명이 시도 [1 예를 들면 : 당신이 원래의 테이블을 건드리지 않고 복제를 만드는 방법입니다 ] [1] : http://stackoverflow.com/questions/4415519/best-w ay-to-remove-duplicate-entries-from-a-data-table –

답변

7

. 당신은 먼저 중복-행을 찾을 수있다 :

var dupGroups = dt.AsEnumerable() 
    .GroupBy(row => row.Field<int>("ITEM")) 
    .Where(g => g.Count() > 1); 

지금 당신이 합계를 얻기 위해 사용할 수 있으며, 테이블에서 중복 행을 제거 할 수 있습니다.

foreach (var group in dupGroups) 
{ 
    DataRow first = group.First(); 
    int sum = group.Sum(r => r.Field<int>("QTY")); 
    first.SetField("QTY", sum); 
    foreach (DataRow row in group.Skip(1)) 
     dt.Rows.Remove(row); 
} 

또는 새 DataTable을 만드는 하나의 쿼리에서.

DataTable newTable = dt.AsEnumerable() 
    .GroupBy(row => row.Field<int>("ITEM")) 
    .Select(g => 
    { 
     DataRow first = g.First(); 
     if (g.Count() > 1) 
     { 
      int sum = g.Sum(r => r.Field<int>("QTY")); 
      first.SetField("QTY", sum); 
     } 
     return first; 
    }) 
    .CopyToDataTable(); 

은 그러나, 두 번째 방법은 새 DataTable을 만들 CopyToDatatable을 사용하기 때문에 바람직하지 않은 될 수있는 원래의 테이블을 수정합니다. 같은 스키마를 가진 빈 테이블을 얻으려면 원래 테이블 ( DataTable newTable = dt.Clone();)을 복제해야합니다. 그런 다음 NewRow + ItemArray.Clone() 또는 table.ImportRow을 사용하여 원본 데이터를 수정하지 않고 실제 클론을 만듭니다.

참조 : C# simple way to copy or clone a DataRow?

편집 :

DataTable newTable = dt.Clone(); 
var itemGroups = dt.AsEnumerable() 
    .GroupBy(row => row.Field<int>("ITEM")); 
foreach (var group in itemGroups) 
{ 
    DataRow first = group.First(); 
    if (group.Count() == 1) 
     newTable.ImportRow(first); 
    else 
    { 
     DataRow clone = newTable.Rows.Add((object[])first.ItemArray.Clone()); 
     int qtySum = group.Sum(r => r.Field<int>("QTY")); 
     clone.SetField("QTY", qtySum); 
    } 
} 
+0

답변과 의견을 보내 주셔서 감사합니다. 두 번째 방법이 도움이됩니다. – Sara

+0

@Sara : 그러나 두 번째 방법은 두 테이블을 미묘하게 수정하기 때문에 가장 위험합니다. 합계 값을 가진 복사 테이블을 만들고 싶다면 새 테이블을 만들고 싶지 않고'table.Clone()'+'ImportRow'를 먼저 쓰면됩니다. –

+0

@Sara : 원본 테이블을 수정하지 않고 합계 데이터로 복제본을 만드는 방법을 보여주는 예제가 추가되었습니다. –

1

DataTable 원래 변경되지 않습니다 : 당신은 Sum을 사용할 수 있습니다

var table = dt.Copy().AsEnumerable() 
         .GroupBy(row=>row["ITEM"]) 
         .Select(g=> { 
           DataRow dr = g.First(); 
           dr.SetField("QTY", g.Sum(x=>x.Field<int>("QTY"))); 
           return dr; 
          }) 
         .CopyToDataTable(); 
+0

'Count()'대신'Sum()'을 사용하면 좋을 것입니다. –

+0

@WillemDuncan 감사합니다. 놓치 셨습니다! –

+0

당신은 또한 어디에서나'dr'을 사용하지 않습니다. – musefan

3
var table = dt.AsEnumerable() 
    .GroupBy(row => row.Field<int>("ITEM")) 
    .Select(group => { 
     var row = group.First(); 
     row['QTY'] = group.Sum(x => x.Field<int>('QTY')); 
     return row; 
    }).CopyToDataTable(); 
+0

그러나 OP는'CopyToDatatable'를 사용하여 새로운'DataTable'을 생성하기 때문에 원하지 않을 수도있는 원본 테이블을 수정합니다. Btw, 같은 문제가있다 [내 두 번째 접근] (http://stackoverflow.com/a/18463169/284240). 원래 테이블을 복제하고'NewRow' +'ItemArray.Clone()'또는'table.ImportRow'를 사용하여 원본 데이터를 수정하지 않고 실제 복제본을 생성해야합니다. –

+0

@TimSchmelter : 당신 말이 맞아요. +1 점 –

+0

@ Cuong Le Thanks. 그것은 작동합니다. 원본을 수정하지만 사소한 문제입니다. – Sara