BulkInsert

tacoyaggi ㅣ 2024. 2. 8. 12:47

BulkInsert 란?

  • 데이터베이스에 한 번에 여러 행을 삽입하는 작업을 가리킴. (대량의 insert를 한번에 한다고 생각하면 됨)
  • 1000번 insert 할걸. 1번에 끝내니까 대량의 데이터를 삽입할 때 효과적 (실제로 Insert 와 비교했을 때 대량 데이터 기준 성능이 우수함)

예제

  • 핵심은 우리가 생성한 DataTable Class에 데이터를 저장하고 해당 DataTable을 복사해서 Insert 하는 개념임.
  • List<BulkEntity> 형태에 값을 저장하고 반복문을 통해 DataTable에 다가 저장함.
  • SqlBulkCopy 클래스를 사용하여 테이블명과 데이터가 저장되어 있는 DataTble을 던짐.
  • 그리고 WriteToServer() 메서드를 통해서 Datable 데이터 복사 후 DB에 저장 됨
using System.Data;
using System.Data.SqlClient;

string connectionString = "연결 DB";

List<BulkEntity> bulkEntities = new List<BulkEntity>();

using (SqlConnection conn = new SqlConnection(connectionString))
{
    conn.Open();

    try
    {
        DataTable dt = new DataTable();
        dt.Columns.Add("No");
        dt.Columns.Add("Name");

        bulkEntities = Bulk.GetBulkData();

        foreach (var item in bulkEntities)
        {
            dt.Rows.Add(item);
        }

        using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connectionString,SqlBulkCopyOptions.Default))
        {
            bulkCopy.DestinationTableName = "테이블명";
            bulkCopy.WriteToServer(dt);
        }
    }
    catch (Exception ex)
    {

    }
}

public class Bulk
{
    public static List<BulkEntity> GetBulkData()
    {
        List<BulkEntity> data = new List<BulkEntity>();

        data.Add(new BulkEntity
        {
            No = 1,
            Name = "tt"
        });

        return data;
    }
}


public class BulkEntity
{
    public int No { get; set; }
    public string Name { get; set; }
}


확장 메서드

  • BulkInsert 는 확장 메서드로 사용 하는게 좋음. (DataTable 구조나 Table 이름이 다 다르기 때문임.)
  • 파라미터를 주목해주기 바람. 필요한 재료 ConnectionString , TableName(실제 DB 테이블명) , List or IEnumerable 타입의 데이터
  • IEnumerable 제네릭을 사용한 이유는 데이터 타입이 다 다를 수 있기 때문임. 테이블명은 무조건 문자열이니까 상관없고
  • 여기서 핵심은 제네릭으로 받은 데이터 타입과 데이터들을 DataTable에 저장하는 거임.
  • 제네릭으로 받은 객체명을 컬럼에 추가하고 데이터들은 DataTable 로우에 들어가게 됨.
  • 그리고 마지막 bulkCopy.WriteToServer(dataTable); 팡! 하면 BulkInsert 완료.
  • 형태가 궁금할 수 있겠지. 아래 처럼 클래스 객체를 던짐 (물론 List or IEnumerable 로 인스턴스 생성은 필수쓰)

public class BulkEntity
{
    public int No { get; set; }
    public string Name { get; set; }
}  



public static void BulkInsert<T>(this SqlConnection cnn, string tableName, IEnumerable<T> data)
    {
        using (var bulkCopy = new SqlBulkCopy(cnn))
        {
            bulkCopy.DestinationTableName = tableName;

            // DataTable을 생성하여 데이터를 복사
            var dataTable = new System.Data.DataTable();
            var properties = typeof(T).GetProperties();

            foreach (var property in properties)
            {
                dataTable.Columns.Add(property.Name, Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType);
            }

            foreach (var item in data)
            {
                DataRow row = dataTable.NewRow();
                foreach (var property in properties)
                {
                    row[property.Name] = property.GetValue(item) ?? DBNull.Value;
                }
                dataTable.Rows.Add(row);
            }

            // Bulk Insert 수행
            bulkCopy.WriteToServer(dataTable);
        }
    }


결론

  • Bulk Insert는 DataTable을 복사후 저장하는 Select Insert 임. (쿼리에서도 Select 한 값을 Insert 하는 것과 같음.)
  • 핵심은 우리가 생성한 DataTable 클래스에 데이터를 잘 넣는 것!
  • DataTable 에 저장하는 데이터 형식이 여러가지이므로 제네릭 확장 메서드를 사용하자!

'SW 기능 > .NET Core' 카테고리의 다른 글

DI  (0) 2024.02.07
Razor  (0) 2024.02.06
Dapper  (2) 2024.02.06
Tag Helper  (0) 2024.02.06
Model Binding  (1) 2024.02.02