using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Dapper;
using System.Diagnostics;
using System.Threading;
namespace BatchInsert
{
class Program
{
staticstring cs = "連線字串";
staticstring truncCommand = @"TRUNCATE TABLE Sample";
staticstring insertCommand = @"
INSERT INTO Sample (T1,T2,T3,T4,N1,N2,N3,N4,D1,D2,D3,D4)
VALUES (@T1,@T2,@T3,@T4,@N1,@N2,@N3,@N4,@D1,@D2,@D3,@D4)";
staticstring updateCommand = @"
UPDATE [dbo].[Sample]
SET [T2] = @T2, [T3] = @T3, [T4] = @T4
,[N1] = @N1, [N2] = @N2, [N3] = @N3, [N4] = @N4
,[D1] = @D1, [D2] = @D2, [D3] = @D3, [D4] = @D4
WHERE T1 = @T1";
staticvoid Main(string[] args)
{
Test(1024);
Test(2048);
Test(4096);
Test(8192);
Console.Read();
}
staticvoid Test(int count)
{
List<DynamicParameters> data = new List<DynamicParameters>();
for (var i = 0; i < count; i++)
{
var d = new DynamicParameters();
d.Add("T1", $"A{i:0000}", System.Data.DbType.String);
d.Add("T2", $"B{i:0000}", System.Data.DbType.String);
d.Add("T3", $"C{i:0000}", System.Data.DbType.String);
d.Add("T4", $"D{i:0000}", System.Data.DbType.String);
d.Add("N1", i, System.Data.DbType.Int32);
d.Add("N2", i, System.Data.DbType.Int32);
d.Add("N3", i, System.Data.DbType.Int32);
d.Add("N4", i, System.Data.DbType.Int32);
d.Add("D1", DateTime.Today.AddDays(i));
d.Add("D2", DateTime.Today.AddDays(i));
d.Add("D3", DateTime.Today.AddDays(i));
d.Add("D4", DateTime.Today.AddDays(i));
data.Add(d);
}
TestDbExecute(data, true, false);
TestDbExecute(data, true, true);
TestDbExecute(data, false, false);
TestDbExecute(data, false, true);
}
staticobject sync = newobject();
staticvoid TestDbExecute(List<DynamicParameters> data,
bool insert, bool parallel)
{
string cmdText = insert ? insertCommand : updateCommand;
using (SqlConnection cn = new SqlConnection(cs))
{
Stopwatch sw = new Stopwatch();
cn.Execute(truncCommand);
sw.Start();
if (!parallel)
{
foreach (var d in data)
{
cn.Execute(cmdText, d);
}
}
else
{
int threadCount = 0;
int maxThreadCount = 0;
Parallel.ForEach(data, (d) =>
{
lock (sync)
{
threadCount++;
if (threadCount > maxThreadCount)
maxThreadCount = threadCount;
}
using (var cnx = new SqlConnection(cs))
{
cnx.ExecuteReader(cmdText, d);
}
Interlocked.Decrement(ref threadCount);
});
Console.WriteLine("[MaxThreads={0}]", maxThreadCount);
}
sw.Stop();
Console.Write("{0} {1} {2}: {3:n0}ms\n",
data.Count, parallel ? "Parallel" : "Loop",
insert ? "Insert": "Update", sw.ElapsedMilliseconds);
}
}
}
}