آخرین فرصت تا %60 تخفیف خرید یکجای دوره ها برای 2 نفر فقط تا
00 00 00

درج انبوه رکورد ها بوسیله SqlBulkCopy در سی شارپ (متد Generic)

در این مطلب با نحوه استفاده از کلاس SqlBulkCopy در سی شارپ برای درج انبوه رکورد ها در سی شارپ آشنا شدیم. در این مطلب با نحوه پیاده سازی یک متد Generic برای Bulk Insert آشنا می شویم. برای پیاده سازی این متد جنریک از قابلیت Reflection در سی شارپ استفاده می کنیم. ساختار جدول مورد استفاده از در این مطلب، همان جدولی است که در مطلب قبلی ایجاد کردیم. در ابتدا یک کلاس به عنوان مدل به صورت زیر تعریف می کنیم:

[Table("SampleTable")]
public class SampleTableModel
{
    [Column("From")]
    public string From { get; set; }
    [Column("To")]
    public string To { get; set; }
    public DateTime Date { get; set; }
    public decimal Balance { get; set; }
}

همانطور که مشاهده می کنید در این کلاس از بعضی Attribute ها مانند Table یا Column استفاده کردیم. استفاده از این Attribute ها برای مشخص کردن نام جدول مقصد که اطلاعات مدل داخل آن درج می شود و نام ستون های معادل هر خصوصیت است. در صورت عدم استفاده از این Attribute ها نام کلاس و نام خصوصیت ها به عنوان نام جدول و ستون معادل در نظر گرفته می شوند. ابتدا نحوه استفاده از متد BulkInsert را با در زیر ببینیم و بعد نحوه پیاده سازی آن را بررسی کنیم:

List<SampleTableModel> models = new List<SampleTableModel>();

for (int i = 0; i < 1000000; i++)
{
    models.Add(new SampleTableModel()
    {
        From = "Hossein Ahmadi",
        To = "Mohammad Nasiri",
        Date = DateTime.UtcNow,
        Balance = 10000
    });
}

BulkInsert(models);

کد بالا نیاز به توضیح زیاده ندارد، تعریف یک لیست از حدود 1 میلیون رکود بر اساس مدلی که ایجاد کردیم و فراخوانی متد BulkInsert برای درج رکوردها، شئ models به عنوان پارامتر ورودی به متد BulkInsert ارسال می شود. اما نحوه پیاده سازی متد BulkInsert رو در زیر مشاهده می کنید:

public static void BulkInsert<T>(List<T> items)
{
    var modelType = typeof(T);
    var properties = modelType.GetProperties();

    DataTable table = new DataTable();
    foreach (var property in properties)
    {
        table.Columns.Add(property.Name, property.PropertyType);
    }
    foreach (var item in items)
    {
        var row = table.NewRow();
        foreach (var property in properties)
        {
            row[property.Name] = property.GetValue(item);
        }
        table.Rows.Add(row);
    }
    using (var cnn = new SqlConnection("data source=.; initial catalog=SampleForBulkInsert; user id=sa; password=1"))
    {
        var bulkCopy = new SqlBulkCopy(cnn);
        foreach (var property in properties)
        {
            var propertyColumn = property.GetCustomAttribute<ColumnAttribute>()?.Name ?? property.Name;
            bulkCopy.ColumnMappings.Add(property.Name, propertyColumn);
        }

        var tableName = modelType.GetCustomAttribute<TableAttribute>()?.Name ?? modelType.Name;
        bulkCopy.DestinationTableName = tableName;
        cnn.Open();
        bulkCopy.WriteToServer(table);
    }
}

در کد بالا، ابتدا بوسیله Reflection نوع پارامتر T و لیست خصوصیت های آن را میگیریم:

var modelType = typeof(T);
var properties = modelType.GetProperties();

قدم بعدی ایجاد DataTable و تعریف ستون های داخل آن بر اساس خصوصیت های مدل است:

DataTable table = new DataTable();
foreach (var property in properties)
{
    table.Columns.Add(property.Name, property.PropertyType);
}

بعد از ایجاد ستون ها، باید بر اساس آیتم های داخل models سطرهای داخل table را ایجاد کنیم:

foreach (var item in items)
{
    var row = table.NewRow();
    foreach (var property in properties)
    {
        row[property.Name] = property.GetValue(item);
    }
    table.Rows.Add(row);
}

حالا آماده ایم که عملیات درج رو انجام بدیم، اما در ابتدا باید Mapping ها رو برای SqlBulkCopy تعریف کنیم که این کار رو بوسیله Reflection و گرفتن Attribute های Table و Column که بر روی کلاس مدل و خصوصیت ها قرار دادیم انجام میدیم:

var bulkCopy = new SqlBulkCopy(cnn);
foreach (var property in properties)
{
    var propertyColumn = property.GetCustomAttribute<ColumnAttribute>()?.Name ?? property.Name;
    bulkCopy.ColumnMappings.Add(property.Name, propertyColumn);
}

var tableName = modelType.GetCustomAttribute<TableAttribute>()?.Name ?? modelType.Name;
bulkCopy.DestinationTableName = tableName;

و در نهایت اجرای عملیات Bulk Insert:

cnn.Open();
bulkCopy.WriteToServer(table);

خاصیت متد BulkInsert این هست که به راحتی بر روی هر مدلی قابل انجام هست و نیازی به نوشتن کدهای مربوط به SqlBulkCopy و تعریف Mapping نیست و این کار به صورت خودکار در داخل متد BulkInsert انجام میشه.

نویسنده: حسین احمدی
منبع: جزیره برنامه نویسی وب سایت توسینسو
هر گونه نشر و کپی برداری با ذکر نام نویسنده و منبع بلامانع است

0 نظر

هیچ نظری ارسال نشده است! اولین نظر برای این مطلب را شما ارسال کنید...

نظر شما
برای ارسال نظر باید وارد شوید.
از سرتاسر توسینسو
تنظیمات حریم خصوصی
تائید صرفنظر