2022年11月21日月曜日

BulkInsertのサブルーチン 

 

BulkInsertのサブルーチン 

https://pg-life.net/csharp/sqlbulkcopy/ 

 とても助かりました。

datatableの項目にnullがあるとNGだったので、以下に修正

 

using System.Data;

    public void BulkInsert<T>(List<T> _list) {

string connectionId = "AppDbConnStr";
using (var conn = new SqlConnection(_config.GetConnectionString(connectionId))) {
conn.Open();
using (var tran = conn.BeginTransaction()) {
try {
var list = _list.ConvertAll(c => (T)c);
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(conn,
SqlBulkCopyOptions.Default,
tran)) {
//タイムアウト指定(デフォルトで30秒)
bulkCopy.BulkCopyTimeout = 60;

//テーブル名指定
bulkCopy.DestinationTableName = typeof(T).Name;

//一括Insert実行
bulkCopy.WriteToServer(ToDataTable<T>(list));

//コミット
tran.Commit();
}
}
catch (Exception) {
//ロールバック
tran.Rollback();
throw;
}
}
}
}

private static DataTable ToDataTable<T>(IEnumerable<T> data) {

var properties = typeof(T).GetProperties();
var typeCasts = new Type[properties.Count()];

for (var i = 0; i < properties.Count(); i++) {
if (properties[i].PropertyType.IsEnum) {
typeCasts[i] = Enum.GetUnderlyingType(properties[i].PropertyType);
}
else {
typeCasts[i] = null;
}
}

var dataTable = new DataTable();
for (var i = 0; i < properties.Count(); i++) {
// Nullable types are not supported.
var propertyNonNullType = Nullable.GetUnderlyingType(properties[i].PropertyType) ?? properties[i].PropertyType;
dataTable.Columns.Add(properties[i].Name, typeCasts[i] == null ? propertyNonNullType : typeCasts[i]);
}

foreach (var item in data) {
var values = new object[properties.Count()];
for (var i = 0; i < properties.Count(); i++) {
var value = properties[i].GetValue(item, null);
values[i] = typeCasts[i] == null ? value : Convert.ChangeType(value, typeCasts[i]);
}

dataTable.Rows.Add(values);
}

return dataTable;
}

 

2022年11月17日木曜日

MSSQL Bulk Insert C#では  System.Data.SqlClient.SqlBulkCopy

 System.Data.SqlClient.SqlBulkCopy を使用すると SQL Server のテーブルに大量データを高速に一括登録することが出来ます。

2022年11月16日水曜日

BulkInsertのサブルーチン 

BulkInsertのサブルーチン 

https://pg-life.net/csharp/sqlbulkcopy/ 

 とても助かりました。

using System.Data;

public static class IEnumerableExtention
{
    public static DataTable ConvertDataTable<T>(this IEnumerable<T> items)
    {
        var properties = typeof(T).GetProperties();
        var result = new DataTable();

        // テーブルレイアウトの作成
        foreach (var prop in properties)
        {
            result.Columns.Add(prop.Name, prop.PropertyType);
        }

        // 値の投げ込み
        foreach (var item in items)
        {
            var row = result.NewRow();
            foreach (var prop in properties)
            {
                var itemValue = prop.GetValue(item, new object[] { });
                row[prop.Name] = itemValue;
            }
            result.Rows.Add(row);
        }
        return result;
    }
}


 

using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;

public static void BulkInsert<T>(List<T> _list)
{
    //環境に応じて変えてください
    var connectionString = "接続文字列";

    using (var connection = new SqlConnection(connectionString))
    {
        connection.Open();
        using (var tran = connection.BeginTransaction())
        {
            try
            {
                var list = _list.ConvertAll(c => (T)c);
                using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection,
                                                              SqlBulkCopyOptions.Default,
                                                              tran))
                {
                    //タイムアウト指定(デフォルトで30秒)
                    bulkCopy.BulkCopyTimeout = 60;
                    //テーブル名指定
                    bulkCopy.DestinationTableName = typeof(T).Name;
                    //一括Insert実行
                    bulkCopy.WriteToServer(list.ConvertDataTable<T>());
                    //コミット
                    tran.Commit();
                }
            }
            catch (Exception)
            {
                //ロールバック
                tran.Rollback();
                throw;
            }
        }
    }
}

 

Dapper BulkInsert 感謝です、素晴らしい

 Dapper BulkInsert 感謝です、素晴らしい

通常のInsert 11757件をCOMMIT無しでSQL発行したら

実行時間は約10秒位になった。

Dapper BulkInsertを使用したら 0.3秒で終了

え、処理速度が違いすぎる 、このライブラリーを作った人に感謝です。

 https://dapper-plus.net/


 よ~く見ると 1 developer $799 / Year なのね

でも そのぐらい支払いしても良いと思うライブラリです。