C#

[C#]DataTable 행(Row) 삭제 방법

DevStory 2021. 8. 8.

MS에서 C#의 DataTable의 행(Row)을 삭제하는 방법으로 Remove 메서드와 Delete 메서드의 사용을 권장합니다.

 

DataTable의 행을 삭제하는 방법을 좀 더 알아보면 Remove, Delete 메서드 이외에 RemoveAt 메서드와 Clear 메서드도 존재합니다. 

 

이번 포스팅에서는 아래 4가지 메서드를 이용하여 DataTable의 행을 삭제하는 방법을 소개합니다.

목차

  1. 지정된 행을 삭제하는 Remove 메서드
  2. 지정된 Index의 행을 삭제하는 RemoveAt 메서드
  3. 모든 행을 삭제하는 Clear 메서드
  4. DataRow에 접근하여 행을 삭제하는 Delete 메서드

샘플 DataTable

아래 그림은 예제로 사용할 DataTable의 구조입니다.


Remove 메서드

지정된 DataRow를 DataTable에서 삭제합니다.

public void Remove (System.Data.DataRow row);

 

아래 코드는 dt의 0번째 index인 DataRow를 dt에서 삭제합니다.

dt.Rows.Remove(dt.Rows[0]);

실행 결과

 

Market이 Lotte인 DataRow를 삭제

Select 메서드를 사용하여 Market이 Lotte인 DataRow를 배열로 생성합니다.

배열의 null 여부와 Length를 체크 후 foreach문으로 Row를 삭제하는 방법입니다.

DataRow[] drs = dt.Select("Market = 'Lotte'");

if(drs != null && drs.Length > 0)
{
  foreach(DataRow row in drs)
  {
    dt.Rows.Remove(row);
  }
}

실행 결과

 

for문 사용하지 마세요.

remove 메서드를 사용하면, 행이 즉시 삭제되어 행의 개수도 변화됩니다.

아래 코드는 for문을 사용하여 모든 행을 삭제할 것 같지만 실제로 다른 결과를 보여줍니다.

for(int loop = 0; loop < dt.Rows.Count; loop++)
{
  Console.WriteLine("loop: " + loop);
  Console.WriteLine("삭제 전: " + dt.Rows.Count);
  dt.Rows.Remove(dt.Rows[loop]);
  Console.WriteLine("삭제 후: " + dt.Rows.Count);
  Console.WriteLine();
}

실행 결과

Console 출력
Datatable 구조


RemoveAt 메서드

지정된 index의 행을 DataTable에서 삭제합니다.

※ Remove 메서드와 마찬가지로 for문은 주의해서 사용해주세요.

public void RemoveAt (int index);

 

아래 코드는 2번째 index의 행을 삭제합니다.

dt.Rows.RemoveAt(2);

실행 결과


Clear 메서드

DataTable의 모든 행을 삭제합니다.

public void Clear ();

 

아래 코드는 dt의 모든 행을 삭제합니다.

dt.Clear();

실행 결과


Delete 메서드

Delete 메서드는 DataTable의 DataRow에 접근하여 사용할 수 있습니다.

아래 코드는 foreach문을 사용하여 DataRow에 접근하여 Delete 메서드를 사용했습니다.

dt.AcceptChanges();
foreach (DataRow row in dt.Rows)
{
  if(row["Market"].ToString() == "Lotte")
  {
    row.Delete();
  }
}

실행 결과

Remove, RemoveAt, Clear 메서드와는 다른 결과를 보여줍니다.

Delete 메서드는 Remove, RemoveAt, Clear 메서드와는 다르게 행이 바로 삭제되지 않고 행이 삭제되었다고 표기를 합니다.

행이 바로 삭제되지 않았으므로 RejectChanges 메서드를 사용하여 복구 가능하며, 완전하게 삭제하기 위해서는 foreach문이 끝난 후 AcceptChange 메서드를 호출해야 합니다.

 

아래 코드는 foreach문이 끝난 후 AcceptChange 메서드를 호출합니다.

dt.AcceptChanges();
foreach (DataRow row in dt.Rows)
{
  if(row["Market"].ToString() == "Lotte")
  {
    row.Delete();
  }
}
dt.AcceptChanges();

실행 결과

 

foreach문 위에 AcceptChange 메서드를 사용한 이유?

foreach문 위에 AcceptChange 메서드를 사용하지 않았을 경우 예외가 발생합니다.

예외 발생

DataTable에는 행의 상태(RowState)라는 게 존재합니다.

  • 행을 추가했으면 Added
  • 행을 수정했으면 Modified
  • 행을 삭제했으면 Deleted
  • 변경사항이 없거나 AcceptChange 메서드를 호출했으면 unchanged

제가 작성한 코드는 Add 메서드를 사용하여 행을 추가했기 때문에 모든 행이 Added 상태입니다.

foreach문을 사용하여 DataRow에 접근하는 경우 unchanged 상태가 하나라도 존재하지 않으면, 예외가 발생합니다.

그래서 foreach문 호출하기 전에 Added 상태인 행을 AcceptChange 메서드를 호출하여 unchanged 상태로 변경하였습니다.

AcceptChange 메서드
DataRow의 값이 추가, 수정, 삭제 행위가 발생하여 값이 변경되었을 경우 변경된 값으로 적용합니다.
변경 사항이 적용된 행의 RowState는 unchanged로 변경됩니다.

 

아래 코드는 삭제된 행을 RejectChanges 메서드를 사용하여 복구합니다.

dt.AcceptChanges();
foreach (DataRow row in dt.Rows)
{
  if(row["Market"].ToString() == "Lotte")
  {
    row.Delete();
  }
}
dt.RejectChanges();

실행 결과


사용된 예제 코드

// 예제로 사용될 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);

// Remove 메서드
/*
dt.Rows.Remove(dt.Rows[0]);
*/

// Remove 메서드 응용 방법
/*
DataRow[] drs = dt.Select("Market = 'Lotte'");

if (drs != null && drs.Length > 0)
{
  foreach (DataRow row in drs)
  {
    dt.Rows.Remove(row);
  }
}
*/

// RemoveAt 메서드
/*
dt.Rows.RemoveAt(2);
*/

// Clear 메서드
/*
dt.Clear();
*/

// Delete 메서드
/*
dt.AcceptChanges();
foreach (DataRow row in dt.Rows)
{
  if(row["Market"].ToString() == "Lotte")
  {
    row.Delete();
  }
}
// 복구
//dt.RejectChanges();

// 삭제 적용
// dt.AcceptChanges();
*/
반응형

댓글