From 6a70b44c036fc2c7bd17f4dcdddb26fe4fd37436 Mon Sep 17 00:00:00 2001 From: sunkaixuan <610262374@qq.com> Date: Tue, 19 Mar 2024 14:01:47 +0800 Subject: [PATCH] BulkMerge support datatable --- .../FastestProvider/FastestProvider.cs | 48 +++++++++++++++++++ .../SqlSugar/Interface/IFastest.cs | 2 + .../SqlSugar/Utilities/UtilMethods.cs | 12 +++++ 3 files changed, 62 insertions(+) diff --git a/Src/Asp.NetCore2/SqlSugar/Abstract/FastestProvider/FastestProvider.cs b/Src/Asp.NetCore2/SqlSugar/Abstract/FastestProvider/FastestProvider.cs index ea7f206f2..3044656ef 100644 --- a/Src/Asp.NetCore2/SqlSugar/Abstract/FastestProvider/FastestProvider.cs +++ b/Src/Asp.NetCore2/SqlSugar/Abstract/FastestProvider/FastestProvider.cs @@ -4,6 +4,9 @@ using System.Data; using System.Text; using System.Threading.Tasks; using System.Linq; +using System.Threading; +using System.Reflection; +using System.Runtime.CompilerServices; namespace SqlSugar { public partial class FastestProvider:IFastest where T:class,new() @@ -179,6 +182,22 @@ namespace SqlSugar { return BulkMergeAsync(datas).GetAwaiter().GetResult(); } + public int BulkMerge(DataTable dataTable, string[] whereColumns,bool isIdentity) + { + object newValue, fastestMethod; + MethodInfo bulkCopyMethod; + _BulkMerge(dataTable, whereColumns, out newValue, out fastestMethod, out bulkCopyMethod,false,isIdentity); + var result = (int)bulkCopyMethod.Invoke(fastestMethod, new object[] { newValue }); + return result; + } + public Task BulkMergeAsync(DataTable dataTable, string[] whereColumns, bool isIdentity) + { + object newValue, fastestMethod; + MethodInfo bulkCopyMethod; + _BulkMerge(dataTable, whereColumns, out newValue, out fastestMethod, out bulkCopyMethod,true,isIdentity); + var result = (Task)bulkCopyMethod.Invoke(fastestMethod, new object[] { newValue }); + return result; + } public Task BulkMergeAsync(List datas, string[] whereColumns) { var updateColumns = entityInfo.Columns.Where(it => !it.IsPrimarykey && !it.IsIdentity && !it.IsOnlyIgnoreUpdate && !it.IsIgnore).Select(it => it.DbColumnName ?? it.PropertyName).ToArray(); @@ -247,6 +266,35 @@ namespace SqlSugar #endregion #region Core + private void _BulkMerge(DataTable dataTable, string[] whereColumns, out object newValue, out object fastestMethod, out MethodInfo bulkCopyMethod,bool isAsync, bool isIdentity) + { + Check.ExceptionEasy(this.AsName.IsNullOrEmpty(), "need .AS(tablaeName) ", "需要 .AS(tablaeName) 设置表名"); + var className = "BulkMerge_" +isIdentity+ this.AsName.GetNonNegativeHashCodeString(); + var builder = this.context.DynamicBuilder().CreateClass(className, new SugarTable() + { + TableName = this.AsName + }); + foreach (DataColumn item in dataTable.Columns) + { + var isPrimaryKey = whereColumns.Any(it => it.EqualCase(item.ColumnName)); + builder.CreateProperty(item.ColumnName, item.DataType, new SugarColumn() + { + IsPrimaryKey = isPrimaryKey, + IsIdentity=isIdentity&& isPrimaryKey + + }); + } + var dicList = this.context.Utilities.DataTableToDictionaryList(dataTable); + var type = builder.WithCache().BuilderType(); + var value = this.context.DynamicBuilder().CreateObjectByType(type, dicList); + newValue = UtilMethods.ConvertToObjectList(type, value); + fastestMethod = this.context.GetType() + .GetMethod("Fastest") + .MakeGenericMethod(type) + .Invoke(this.context, null); + bulkCopyMethod = fastestMethod.GetType().GetMyMethod(isAsync? "BulkMergeAsync" : "BulkMerge", 1); + } + private async Task _BulkUpdate(List datas, string[] whereColumns, string[] updateColumns) { try diff --git a/Src/Asp.NetCore2/SqlSugar/Interface/IFastest.cs b/Src/Asp.NetCore2/SqlSugar/Interface/IFastest.cs index 9cbe0c9c0..7e969996d 100644 --- a/Src/Asp.NetCore2/SqlSugar/Interface/IFastest.cs +++ b/Src/Asp.NetCore2/SqlSugar/Interface/IFastest.cs @@ -36,6 +36,8 @@ namespace SqlSugar SplitFastest SplitTable(); Task BulkMergeAsync(List datas); int BulkMerge(List datas); + int BulkMerge(DataTable dataTable, string[] whereColumns,bool isIdentity); + Task BulkMergeAsync(DataTable dataTable, string[] whereColumns, bool isIdentity); Task BulkMergeAsync(List datas, string[] whereColumns); int BulkMerge(List datas, string[] whereColumns); Task BulkMergeAsync(List datas, string[] whereColumns, string[] updateColumns); diff --git a/Src/Asp.NetCore2/SqlSugar/Utilities/UtilMethods.cs b/Src/Asp.NetCore2/SqlSugar/Utilities/UtilMethods.cs index 23b08283c..3136d884e 100644 --- a/Src/Asp.NetCore2/SqlSugar/Utilities/UtilMethods.cs +++ b/Src/Asp.NetCore2/SqlSugar/Utilities/UtilMethods.cs @@ -18,6 +18,18 @@ namespace SqlSugar { public class UtilMethods { + public static object ConvertToObjectList(Type targetType, List sourceList) + { + // 创建 List 类型的实例 + object resultList = Activator.CreateInstance(typeof(List<>).MakeGenericType(targetType)); + // 获取 Add 方法 + var addMethod = resultList.GetType().GetMethod("Add"); + foreach (var obj in sourceList) + { + addMethod.Invoke(resultList, new object[] { obj }); + } + return resultList; + } public static Dictionary DataRowToDictionary(DataRow row) { Dictionary dictionary = new Dictionary();