[C#] 엔터티 클래스와 DataTable 간의 상호 변환, 엔터티 반영 동적 순회 열

실제 프로젝트에서는 데이터 간의 상호 변환이 자주 사용되며 직렬화 및 역직렬화가 일반적인 시나리오입니다. 여기서는 다양한 비즈니스 시나리오에서 사용할 수 있는 엔터티 클래스와 DataTable 간의 변환에 대해서만 간단히 설명합니다.

1. 데이터 테이블을 모델로

C# DataTable을 Model 엔터티 클래스로 변환하려면 리플렉션을 사용하여 DataTable 열과 값을 가져오고 Model 클래스를 인스턴스화하여 값을 할당할 수 있습니다.

1) DataTable을 모델 클래스로 변환

  • 샘플 코드
using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;

public static class DataTableExtensions
{
    
    
    public static List<T> ToList<T>(this DataTable dataTable) where T : class, new()
    {
    
    
        List<T> list = new List<T>();

        foreach (DataRow row in dataTable.Rows)
        {
    
    
            T obj = new T();

            foreach (DataColumn col in dataTable.Columns)
            {
    
    
                PropertyInfo property = typeof(T).GetProperty(col.ColumnName);
                if (property != null && row[col] != DBNull.Value)
                {
    
    
                    property.SetValue(obj, row[col]);
                }
            }

            list.Add(obj);
        }

        return list;
    }
}

2) DataTable은 지정된 Model 엔터티 클래스로 변환됩니다.

public class Person
{
    
    
    public int Id {
    
     get; set; }
    public string Name {
    
     get; set; }
    public int Age {
    
     get; set; }
}

DataTable dataTable = new DataTable();
dataTable.Columns.Add("Id", typeof(int));
dataTable.Columns.Add("Name", typeof(string));
dataTable.Columns.Add("Age", typeof(int));

dataTable.Rows.Add(1, "John", 25);
dataTable.Rows.Add(2, "Jane", 30);
dataTable.Rows.Add(3, "Mike", 40);

List<Person> persons = dataTable.ToList<Person>();
  • 실행 결과
    여기에 이미지 설명 삽입

위의 코드는 DataTable 데이터가 포함된 List of Person 엔터티 클래스를 만듭니다. 각 열의 데이터는 Person의 해당 속성에 할당됩니다.
위의 예에서 Person 클래스는 단지 예일 뿐이며 필요에 따라 사용자 지정 엔터티 클래스를 만들고 DataTable의 열 이름 및 유형에 따라 특성을 일치시킬 수 있습니다. 또한 해당 속성이 존재하고 열의 값 유형이 속성 유형과 호환되는지 확인해야 합니다.

2. DataTable로 모델링

리플렉션을 통해 C# 엔터티를 DataTable로 변환하려면 System.Reflection 네임스페이스의 클래스를 사용하여 엔터티의 속성 및 값에 액세스하고 이를 DataTable에 추가할 수 있습니다.
1) 리플렉션을 사용하여 엔터티를 DataTable로 변환

using System;
using System.Data;
using System.Reflection;

public static class EntityExtensions
{
    
    
    public static DataTable ToDataTable<T>(this T[] entities)
    {
    
    
        DataTable dataTable = new DataTable(typeof(T).Name);

        PropertyInfo[] properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);

        foreach (PropertyInfo propInfo in properties)
        {
    
    
            dataTable.Columns.Add(propInfo.Name, propInfo.PropertyType);
        }

        foreach (T entity in entities)
        {
    
    
            object[] values = new object[properties.Length];
            for (int i = 0; i < properties.Length; i++)
            {
    
    
                values[i] = properties[i].GetValue(entity);
            }

            dataTable.Rows.Add(values);
        }

        return dataTable;
    }
}

2) 엔티티 배열을 DataTable로 변환

public class Person
{
    
    
    public int Id {
    
     get; set; }
    public string Name {
    
     get; set; }
    public int Age {
    
     get; set; }
}

Person[] persons = new Person[]
{
    
    
    new Person {
    
     Id = 1, Name = "John", Age = 25 },
    new Person {
    
     Id = 2, Name = "Jane", Age = 30 },
    new Person {
    
     Id = 3, Name = "Mike", Age = 40 }
};

DataTable dataTable = persons.ToDataTable();
  • 실행 결과
    여기에 이미지 설명 삽입

위의 코드는 Person 엔터티 배열의 데이터를 포함하는 DataTable을 생성합니다. 각 특성은 DataTable의 열이 되고 각 엔터티 인스턴스는 DataTable의 행을 형성합니다.
위의 예에서 엔티티 클래스 Person은 하나의 예일 뿐이며 필요에 따라 사용자 정의 엔티티 클래스를 생성하고 해당 속성 및 유형을 사용할 수 있습니다.

3. 성찰의 개념

C#의 리플렉션은 런타임에 어셈블리, 형식, 멤버(예: 필드, 속성, 메서드 등)를 가져오고 검사하고 조작하는 기능을 말합니다. 리플렉션은 런타임에 어셈블리 및 형식 정보를 동적으로 얻고 이 정보를 사용하여 개체를 만들고, 메서드를 호출하고, 속성에 액세스하는 등의 작업을 수행할 수 있는 일련의 클래스 및 메서드를 제공합니다.

다음은 몇 가지 주요 개념과 용도입니다.

3.1, 유형 유형

Type 유형은 리플렉션의 핵심이며 런타임에 로드된 유형을 나타냅니다. Type 형식은 이름, 기본 클래스, 구현된 인터페이스, 속성, 메서드, 필드 등과 같은 형식 정보를 얻기 위한 메서드 및 속성을 제공합니다. 유형 유형을 사용하면 유형 정보를 동적으로 얻고 조작할 수 있습니다.

3.2, 조립 조립

Assembly 형식은 실행 파일, 동적으로 연결된 라이브러리 또는 코드용 컨테이너를 포함하는 논리 단위인 어셈블리를 나타냅니다. 리플렉션을 통해 형식, 멤버, 특성 등을 비롯한 어셈블리 정보를 로드하고 검사할 수 있습니다. 어셈블리 유형을 사용하여 어셈블리를 로드하고, 어셈블리에서 유형을 가져오고, 객체를 생성하는 등의 작업을 수행할 수 있습니다.

3.3, MemberInfo 회원 정보

MemberInfo 형식은 필드, 속성, 메서드, 이벤트 등과 같은 형식의 멤버를 나타냅니다. 멤버의 이름, 유형 및 액세스 한정자와 같은 정보를 얻는 방법을 제공합니다.

3.4, PropertyInfo 속성 정보

PropertyInfo 유형은 유형의 속성을 나타내며 속성 값을 가져오고 설정하기 위한 메서드와 속성을 제공합니다.

리플렉션을 사용하면 다음과 같은 많은 동적 및 유연한 기능을 구현할 수 있습니다.

  • 동적으로 객체 생성 및 메서드 호출: 런타임 시 유형 정보를 기반으로 객체를 동적으로 생성하고 객체의 메서드를 호출합니다.
  • 동적으로 속성 값 액세스 및 수정: 런타임에 개체 속성 정보를 얻고 속성 값을 동적으로 수정합니다.
  • 유형 정보 가져오기 및 검사: 런타임에 이름, 기본 클래스, 구현된 인터페이스, 멤버 등과 같은 유형 정보를 가져옵니다.
  • 외부 어셈블리 로드 및 사용: 외부 어셈블리를 동적으로 로드하고 사용하여 런타임 시 유형 및 멤버에 액세스하고 조작합니다.
  • 일반 코드 작성: 리플렉션을 사용하여 다양한 형식과 멤버에 맞게 조정되는 일반적이고 유연한 코드를 작성합니다.

리플렉션은 런타임에 타입 정보를 얻고 확인해야 하기 때문에 어느 정도 성능 손실을 가져온다는 점에 유의해야 합니다. 따라서 리플렉션을 사용할 때는 성능과 유연성의 관계를 따져볼 필요가 있으며, 불필요한 리플렉션 작업을 하지 않도록 주의를 기울여야 합니다.

4. 자주 묻는 질문

1) 엔티티 클래스의 멤버가 nullable 타입으로 정의되어 있을 때 처리하지 않으면 에러가 발생함 2
여기에 이미지 설명 삽입
여기에 이미지 설명 삽입
) DataSet에서 System.Nullable<> 타입의 직접적인 사용은 사실상 지원하지 않는다.

DataTable 열에서 nullable 유형을 사용하려면 System.Object 유형을 사용하고 필요할 때 null 값을 나타내도록 DBNull.Value로 설정할 수 있습니다.

DataTable dataTable = new DataTable();

// 添加可为空的整数列
DataColumn nullableIntColumn = new DataColumn("NullableInt", typeof(object));
dataTable.Columns.Add(nullableIntColumn);

// 添加可为空的字符串列
DataColumn nullableStringColumn = new DataColumn("NullableString", typeof(object));
dataTable.Columns.Add(nullableStringColumn);

위의 코드에서 DataTable 개체 dataTable을 만들고 NullableInt 및 NullableString이라는 두 개의 열을 추가했습니다.

열을 nullable 유형으로 정의하기 위해 typeof(object)를 사용하여 임의의 개체를 허용하는 열의 유형을 정의하고 필요할 때 null 값을 나타내도록 DBNull.Value로 설정할 수 있습니다.

3) DataTable의 열에 null 허용 값을 저장합니다. 예를 들면 다음과 같습니다.

DataRow row = dataTable.NewRow();
row["NullableInt"] = DBNull.Value; // 可空整数为空,使用 DBNull.Value 表示
row["NullableString"] = DBNull.Value; // 可空字符串为空,使用 DBNull.Value 表示
dataTable.Rows.Add(row);

이러한 방식으로 DataTable 열에서 null 허용 형식을 처리하고 DBNull.Value를 사용하여 null 값을 나타낼 수 있습니다. 데이터를 읽고 처리할 때 컬럼의 값이 DBNull.Value인지 확인하여 null 여부를 판단해야 합니다.

Supongo que te gusta

Origin blog.csdn.net/lmy_520/article/details/131512035
Recomendado
Clasificación