Files
jinko.yikatong/Src/Dlhis.ScheduledTask/Extensions/DbConnectionExtensions.cs
2024-01-04 14:40:04 +08:00

123 lines
3.6 KiB
C#

using log4net;
using System.Data.SqlClient;
using System.Data;
using Dapper;
using Dlhis.ScheduledTask.Job;
namespace Dlhis.ScheduledTask.Extensions
{
public static class DbConnectionExtensions
{
private static readonly ILog log = LogManager.GetLogger(typeof(JinkoHrJob));
public static void BulkcopyInsert<T>(this IDbConnection conn, string tableName, List<T> data)
{
using (var bulkcopy = new SqlBulkCopy(conn as SqlConnection))
{
bulkcopy.BatchSize = 10000;
bulkcopy.BulkCopyTimeout = 60;
bulkcopy.DestinationTableName = tableName;
var dt = ToDataTable(data);
foreach (DataColumn column in dt.Columns)
{
bulkcopy.ColumnMappings.Add(new SqlBulkCopyColumnMapping(column.ColumnName, column.ColumnName));
}
bulkcopy.WriteToServer(dt);
}
}
private static DataTable ToDataTable<T>(List<T> data)
{
var dt = new DataTable();
var properties = typeof(T).GetProperties();//.Where(x => x.IsDefined(typeof(CopyAttribute), false));
foreach (var property in properties)
{
dt.Columns.Add(property.Name, Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType);
}
foreach (var item in data)
{
var values = new object[properties.Length];
for (int i = 0; i < properties.Length; i++)
{
if (properties[i].PropertyType == typeof(DateTime?))
{
var o = (DateTime?)properties[i].GetValue(item);
if (!o.HasValue || o.Value == DateTime.MinValue)
{
o = new DateTime(1900, 1, 1);
}
values[i] = o;
}
else
{
var o = properties[i].GetValue(item);
values[i] = o;
}
}
dt.Rows.Add(values);
}
return dt;
}
public static void BulkcopyUpdate<T>(this IDbConnection conn, string targetTableName, List<T> data)
{
var tmpTable = "#tmp_" + targetTableName;
try
{
//go 语法错误 ???
conn.Execute($@"
if object_id('tempdb..{tmpTable}') is not null
drop table {tmpTable}");
conn.Execute($@"
select *
into {tmpTable}
from {targetTableName} where 1=2 ;");
conn.BulkcopyInsert(tmpTable, data);
var properties = typeof(T).GetProperties();
var updates = properties.Where(x => !x.Name.Equals("ename"))
.Where(x => !x.Name.Equals("id"))
.Where(x => !x.Name.Equals("timeid"))
.Select(x =>
{
return $"T.{x.Name}=S.{x.Name}";
});
var updateScript = string.Join(",", updates);
var merge = $@"
Merge into {targetTableName} AS T
Using {tmpTable} AS S
ON T.ename = S.ename
WHEN MATCHED
THEN UPDATE SET {updateScript} ;
";
conn.Execute(merge);
}
catch (Exception ex)
{
log.Error($"批量更新失败:{ex.Message}", ex);
}
finally
{
conn.Execute($@"
drop table {tmpTable}
"
);
}
}
}
}