C#

[C#]DataRow 배열을 DataTable로 변환하는 방법

DevStory 2021. 8. 9.

C#에서 DataRow의 배열DataTable로 만들어야 하는 경우가 종종 발생합니다.

이번 포스팅에서는 DataRow의 배열DataTable로 만드는 방법에 대해 정리합니다.

 

DataTable로 만드는 방법

  • CopyToDataTable 메서드 사용
  • 반복문을 사용하여 DataTable에 Row를 추가하는 방법

CopyToDataTable 메서드

아래 코드는 DataRowArray라는 DataRow 배열을 dtConvert에 DataTable로 생성합니다.

DataTable dtConvert = null;

if(dataRowArray != null && dataRowArray.Length > 0)
{
  dtConvert = dataRowArray.CopyToDataTable();
}

if문으로 null 체크과 Length 체크를 했는데요.

만약, DataRow 배열null 또는 Length0일 경우 CopyToDataTable 메서드에서 예외가 발생하기 때문에 null 체크와 Length 체크를 합니다.

 

CopyToDataTable 메서드는 DataRow 배열에서 Deleted 또는 Detached 상태인 행이 있을 경우 예외를 발생합니다.

아래 코드는 foreach문을 사용하여 DataRow의 Market 컬럼이 "Lotte"인 행을 Deleted 상태로 만들고 dataRowArray를 DataTable로 생성합니다.

foreach(DataRow row in dataRowArray)
{
  // row의 상태를 Added -> Unchanged
  row.AcceptChanges();
  
  if(row["Market"].ToString() == "Lotte")
  {
    // row의 상태를 Unchanged -> Deleted
    row.Delete();
  }
}

DataTable dtConvert = null;

if(dataRowArray != null && dataRowArray.Length > 0)
{
  dtConvert = dataRowArray.CopyToDataTable();
}

실행 결과

하지만, 예외가 발생합니다. 구글링 해도 해결 방법이 나오지 않습니다.

이러한 경우에는 반복문을 사용하여 DataTable에 Row를 추가하는 방법으로 코드를 변경해야 합니다.

 

CopyToDataTable 메서드는 RowState를 복사하지 않습니다.

CopyToDataTable 메서드는 DataRow 배열에서 각 행의 상태(RowState)를 복사하지 않습니다.

Console.WriteLine("*****dataRowArray*****");
foreach (DataRow row in dataRowArray)
{
  Console.WriteLine("dataRowArray 각 행의 DataRowState : " + row.RowState.ToString());
}

DataTable dtConvert = null;

if(dataRowArray != null && dataRowArray.Length > 0)
{
  dtConvert = dataRowArray.CopyToDataTable();
}

if (dtConvert != null && dtConvert.Rows.Count > 0)
{
  Console.WriteLine("*****dtConvert*****");
  foreach (DataRow row in dtConvert.Rows)
  {
    Console.WriteLine("dtConvert 각 행의 DataRowState : " + row.RowState.ToString());
  }
}

실행 결과

dataRowArray의 각 행의 RowStateAdded입니다.

CopyToDataTable 메서드를 사용하여 생성된 dtConvert의 각 행의 RowStateUnchanged입니다.


사용된 예제 코드

// 예제로 사용될 DataTable 생성
DataTable dt = new DataTable();

// 컬럼 생성
dt.Columns.Add("Market", typeof(string));
dt.Columns.Add("Fruit", typeof(string));
dt.Columns.Add("Price", typeof(int));
dt.Columns.Add("Count", typeof(int));

// 행 추가
dt.Rows.Add("Lotte", "Apple", 2000, 10);
dt.Rows.Add("Lotte", "Banana", 3000, 5);

dt.Rows.Add("Homeplus", "Apple", 1500, 50);
dt.Rows.Add("Homeplus", "Banana", 2500, 10);

dt.Rows.Add("Emart", "Apple", 3000, 25);
dt.Rows.Add("Emart", "Banana", 2000, 5);

dt.Rows.Add("GS", "Apple", 1500, 10);
dt.Rows.Add("GS", "Banana", 3000, 20);

// Select 메서드를 사용하여 DataTable의 Row를 DataRow Array로 생성합니다.
DataRow[] dataRowArray = dt.Select();

// CopyToDataTable 메서드 기본 사용 방법
/*
if (dataRowArray != null && dataRowArray.Length >0)
{
  dtConvert = dataRowArray.CopyToDataTable();
}
*/

// Delete 또는 Deleted가 존재하는 경우
/*
foreach (DataRow row in dataRowArray)
{
  row.AcceptChanges();

  if (row["Market"].ToString() == "Lotte")
  {
    row.Delete();
  }
}

DataTable dtConvert = null;

if (dataRowArray != null && dataRowArray.Length > 0)
{
  dtConvert = dataRowArray.CopyToDataTable();
}
*/

// RowState 확인하는 코드
/*
Console.WriteLine("*****dataRowArray*****");
foreach (DataRow row in dataRowArray)
{
  Console.WriteLine("dataRowArray 각 행의 RowState : " + row.RowState.ToString());
}

DataTable dtConvert = null;

if(dataRowArray != null && dataRowArray.Length > 0)
{
  dtConvert = dataRowArray.CopyToDataTable();
}

Console.WriteLine();

if (dtConvert != null && dtConvert.Rows.Count > 0)
{
  Console.WriteLine("*****dtConvert*****");
  foreach (DataRow row in dtConvert.Rows)
  {
    Console.WriteLine("dtConvert 각 행의 RowState : " + row.RowState.ToString());
  }
}
*/

반복문을 사용하여 DataTable에 Row를 추가하는 방법

DataTable 객체 생성 후 ImportRow 메서드를 사용하여 Row를 추가합니다.

Deleted를 포함한 RowState가 복사되며,  Detached 상태는 Unchanged로 변경됩니다.

DataTable dtConvert = new DataTable();

if (dataRowArray != null && dataRowArray.Length > 0)
{
  foreach (DataRow row in dataRowArray)
  {
    dtConvert.ImportRow(row);
  }
}

정리

DataRow 배열의 각 RowState가 Deleted 또는 Detached 상태가 아닐 경우 CopyToDataTable 메서드를 사용하는 것이 좋지만, Deleted 또는 Detached 제외한 RowState는 Unchanged로 변경됩니다.

 

CopyToDataTable 메서드를 자주 사용했는데, 공부하면 할수록 문제가 많은 메서드인 것 같습니다.

반응형

댓글