C#

[C#]DataTable을 List로 변환

DevStory 2022. 5. 1.

DataTable을 List로 변환

이번 포스팅은 C#에서 DataTable을 List로 변환하는 다양한 방법을 소개합니다. C#에서 DataTable을 List로 변환해주는 메서드는 존재하지 않으므로 아래 예제들을 참고하여 경우에 따라 적용하면 되겠습니다.


반복문 사용

아래 예제는 for문을 사용하여 DataTable을 List로 변환합니다.

class Person
{
  public string name { get; set; }
  public int age { get; set; }
  public string address {get; set;}
}

class Program
{
  static void Main(string[] args)
  {
    DataTable dt = new DataTable("Person");
    
    dt.Columns.Add("name", typeof(string));
    dt.Columns.Add("age", typeof(int));
    dt.Columns.Add("address", typeof(string));

    dt.Rows.Add("둘리", 20, "우주");
    dt.Rows.Add("또치", 30, "동물원");
    dt.Rows.Add("마이콜", 40, "지구");

    List<Person> personList = new List<Person>();

    for (int loop = 0; loop < dt.Rows.Count; loop++)
    {
      Person pesron = new Person();

      pesron.name = (dt.Rows[loop]["name"]).ToString();
      pesron.age = Convert.ToInt32(dt.Rows[loop]["age"]);
      pesron.address = (dt.Rows[loop]["address"]).ToString)(;

      personList.Add(pesron);
    }

    for(int loop = 0; loop < personList.Count; loop++)
    {
      Console.WriteLine("name: {0}, age: {1}, address: {2}",
        personList[loop].name,
        personList[loop].age,
        personList[loop].address);
    }
  }
}

실행 결과

name: 둘리, age: 20, address: 우주
name: 또치, age: 30, address: 동물원
name: 마이콜, age: 40, address: 지구

for문을 사용하는 방법은 가장 쉽지만, 변환해야 하는 컬럼이 많을수록 코드가 길어지는 단점이 존재합니다. 그리고 DataTable의 값을 List에 할당하는 과정에서 컬럼명을 잘못 입력하면 컴파일 에러가 발생할 수 있습니다.

반응형

Linq 사용

아래 예제는 Linq를 사용하여 DataTable을 List로 변환합니다.

class Person
{
  public string name { get; set; }
  public int age { get; set; }
  public string address {get; set;}
}

class Program
{
  static void Main(string[] args)
  {
    DataTable dt = new DataTable("Person");
    
    dt.Columns.Add("name", typeof(string));
    dt.Columns.Add("age", typeof(int));
    dt.Columns.Add("address", typeof(string));

    dt.Rows.Add("둘리", 20, "우주");
    dt.Rows.Add("또치", 30, "동물원");
    dt.Rows.Add("마이콜", 40, "지구");

    List<Person> personList = new List<Person>();

    personList = (from DataRow dr in dt.Rows
                   select new Person()
                   {
                     name = (dr["name"]).ToString(),
                     age = Convert.ToInt32(dr["age"]),
                     address = (dr["address"]).ToString()
                   }).ToList();
                   
    for(int loop = 0; loop < personList.Count; loop++)
    {
      Console.WriteLine("name: {0}, age: {1}, address: {2}",
        personList[loop].name,
        personList[loop].age,
        personList[loop].address);
    }
  }
}

실행 결과

name: 둘리, age: 20, address: 우주
name: 또치, age: 30, address: 동물원
name: 마이콜, age: 40, address: 지구

Linq를 사용하는 방법은 for문에 비해 심플하지만, 일일이 값을 할당해야하는 점은 동일합니다.

 

for문과 Linq를 사용하여 DataTable을 다양한 클래스로 변환해야하는 경우 코드가 길어진다는 문제가 존재합니다.


제네릭 메서드 사용

다음은 제네릭 메서드를 구현하여 DataTable을 List로 변환하는 방법입니다. 메서드를 재사용할 수 있으므로 코드가 더 깔끔하다는 장점이 있습니다.

 

만약, DataTable의 컬럼 이름과 List 클래스 필드 이름이 동일하지 않으면, 해당 컬럼은 List로 변환되지 않습니다.

class Person
{
  public string name { get; set; }
  public int age { get; set; }
  public string address {get; set;}
}

class Program
{
  private static List<T> ConvertDataTable<T>(DataTable dt)  
  {  
    List<T> data = new List<T>();  
    foreach (DataRow row in dt.Rows)  
    {  
      T item = GetItem<T>(row);  
      data.Add(item);  
    }  
    return data;  
  }

  private static T GetItem<T>(DataRow dr)  
  {  
    Type temp = typeof(T);  
    T obj = Activator.CreateInstance<T>();  
  
    foreach (DataColumn column in dr.Table.Columns)  
    {  
      foreach (PropertyInfo pro in temp.GetProperties())  
      {  
        if (pro.Name == column.ColumnName)  
          pro.SetValue(obj, dr[column.ColumnName], null);  
        else  
          continue;  
      }  
    }  
    return obj;  
  }
  
  static void Main(string[] args)
  {
    DataTable dt = new DataTable("Person");
    
    dt.Columns.Add("name", typeof(string));
    dt.Columns.Add("age", typeof(int));
    dt.Columns.Add("address", typeof(string));

    dt.Rows.Add("둘리", 20, "우주");
    dt.Rows.Add("또치", 30, "동물원");
    dt.Rows.Add("마이콜", 40, "지구");

    List<Person> personList = new List<Person>();

    // DataTable을 List로 변환
    personList = ConvertDataTable<Person>(dt);
                   
    for(int loop = 0; loop < personList.Count; loop++)
    {
      Console.WriteLine("name: {0}, age: {1}, address: {2}",
        personList[loop].name,
        personList[loop].age,
        personList[loop].address);
    }
  }
}

실행 결과

name: 둘리, age: 20, address: 우주
name: 또치, age: 30, address: 동물원
name: 마이콜, age: 40, address: 지구

DataTable을 List로 변환하는 과정에서 3중 for문을 수행하므로 성능이 좋지 않습니다. DataTable의 컬럼(Column)과 로우(Row)가 많다면 상당히 느릴 수 있습니다.

반응형

'C#' 카테고리의 다른 글

[C#]생성자(Constructor)  (0) 2022.05.05
[C#]소멸자(destructor)  (0) 2022.05.02
[C#]텍스트 파일 쓰기  (0) 2022.05.01
[C#]람다식, 람다표현식(Lambda expression)  (0) 2022.05.01
[C#]SortedList 클래스  (0) 2022.02.06

댓글