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 에 저장하는 데이터 형식이 여러가지이므로 제네릭 확장 메서드를 사용하자!