C# ile SqlClient.SqlBulkCopy Kullanımı:
C# kodları ile yapılan uygulamalarda yüzbinlerce satırlık verinin bir döngü içerisinde Sql Server'daki veritabanına aktarmak başka bir değişle insert etmek oldukça zaman alıcı ve donanım tüketici olmaktadır.
Bu tür durumlarda SqlClient sınıfının SqlBulkCopy özelliğini kullanmak en ideal yöntem olacaktır. Bu yöntemi kullanabilmek için insert işleminin gerçekleşmesi gerektiği hedef tablo ile birebir kaynak tablonun oluşturulması gerekmektedir. Hedef tablo verilerin kalıcı olarak kaydedileceği fiziksel tablo olduğunu düşünürsek kaynak tablo ise onunla birebir aynı olması gereken ve ön bellekte oluşturmamız gereken geçici tablo olacaktır.
- Verilerin aktarılacağı veritabanındaki fiziksel tablo olan hedef tablonun sütun sayısı, sütun adları ve sütun veri tipleri ile birebir olan kaynak tablo aşağıdaki gibi create edilir.
public class Kaynak_TABLE
{
[Key]
public int ID { get; set; }
public string job_code { get; set; }
public string recipe_code { get; set; }
public string recipe_name { get; set; }
public double flotte { get; set; }
public string mach_name { get; set; }
public string tank_name { get; set; }
public DateTime start_time { get; set; }
public DateTime end_time { get; set; }
public int CONNECTLY { get; set; }
// Insert olayı için önbellekte oluşturulması gereken veri kaynağı DataSet'in interface'i aşağıdaki gibidir.
public void InsertMassiveData(IEnumerable<Kaynak_TABLE> Kaynak_List)
{
var table = new DataTable();
table.Columns.Add("ID", typeof(int));
table.Columns.Add("job_code", typeof(string));
table.Columns.Add("recipe_code", typeof(string));
table.Columns.Add("recipe_name", typeof(string));
table.Columns.Add("flotte", typeof(float));
table.Columns.Add("mach_name", typeof(string));
table.Columns.Add("tank_name", typeof(string));
table.Columns.Add("start_time", typeof(DateTime));
table.Columns.Add("end_time", typeof(DateTime));
table.Columns.Add("CONNECTLY", typeof(int));
foreach (var itemDetail in Consumptions_List)
{
table.Rows.Add(new object[]
{
itemDetail.ID,
itemDetail.job_code,
itemDetail.recipe_code,
itemDetail.recipe_name,
itemDetail.flotte,
itemDetail.mach_name,
itemDetail.tank_name,
itemDetail.start_time,
itemDetail.CONNECTLY
});
}
//Insert to db..
using (var MSConn = FnSQL.SqlConnectionNew)
{// Sql bağlantının tanımlı olduğu fonksiyonun kullanımı ..
using (SqlTransaction transaction = MSConn.BeginTransaction())
{// Sql Transaction kullanımı..
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(MSConn, SqlBulkCopyOptions.Default, transaction))
{//SqlBulkCopy sınıfının kullanımı..
try
{//DestinationTableName veritabanında tanımlı olan fiziksel tablonun adıdır.
bulkCopy.DestinationTableName = "Hedef_Table";
bulkCopy.WriteToServer(table);
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
MSConn.Close();
}
}
}
}
}
}
Yukarıda oluşturmuş olduğumuz Yapının Kullanımı Aşağıdaki Gibidir:
while (xReaderKaynak_Table.Read())
{
xKaynak_Table = new Kaynak_Table();
xKaynak_Table.ID = kayit;
xKaynak_Table.job_code = FnString.IsNull(xReaderKaynak_Table["jobcode"]);
xKaynak_Table.recipe_code = FnString.IsNull(xReaderKaynak_Table["recipe_code"]);
xKaynak_Table.recipe_name = FnString.IsNull(xReaderKaynak_Table["recipe_name"]);
xKaynak_Table.flotte = Convert.ToDouble(xReaderKaynak_Table["flotte"]);
xKaynak_Table.mach_name = FnString.IsNull(xReaderKaynak_Table["mach_name"]);
xKaynak_Table.tank_name = FnString.IsNull(xReaderKaynak_Table["tankname"]);
xKaynak_Table.start_time = FnDate.IsNull(xReaderKaynak_Table["start_time"]);
if (xKaynak_Table.start_time == DateTime.MinValue)
{
xKaynak_Table.start_time = FnDate.IsNull(xReaderKaynak_Table["start_time"]);
}
xKaynak_Table.end_time = FnDate.IsNull(xReaderKaynak_Table["end_time"]);
if (xKaynak_Table.end_time == DateTime.MinValue)
{
xKaynak_Table.end_time = FnDate.IsNull(xReaderKaynak_Table["end_time"]);
}
Kaynak_Table.Add(xKaynak_Table);
}
- Ve sonuç olarak yukarıda yüzbinlerce verinin önbellekte oluşturulmuş kaynak tablonun içine kaydedildiği DataTable objesi tek bir insert komutuyla gönderimi aşağıdaki gibidir :
Kaynak_Table aKaynak_Table = new Kaynak_Table();
aKaynak_Table.InsertMassiveData(Kaynak_Table);