From 7d35bbf02afb7003a62c7685d66aede66502da52 Mon Sep 17 00:00:00 2001 From: sunkaixuan <610262374@qq.com> Date: Mon, 24 Apr 2023 19:45:11 +0800 Subject: [PATCH] Oracle BulkcopyUpdate by datatable --- .../FastestProvider/FastestProvider.cs | 2 +- .../Abstract/FastestProvider/Private.cs | 46 +++++++++++++++++++ .../Oracle/SqlBuilder/OracleFastBuilder.cs | 31 ++++++++----- 3 files changed, 67 insertions(+), 12 deletions(-) diff --git a/Src/Asp.NetCore2/SqlSugar/Abstract/FastestProvider/FastestProvider.cs b/Src/Asp.NetCore2/SqlSugar/Abstract/FastestProvider/FastestProvider.cs index 439a80b8e..811609720 100644 --- a/Src/Asp.NetCore2/SqlSugar/Abstract/FastestProvider/FastestProvider.cs +++ b/Src/Asp.NetCore2/SqlSugar/Abstract/FastestProvider/FastestProvider.cs @@ -232,7 +232,7 @@ namespace SqlSugar var isAuto = this.context.CurrentConnectionConfig.IsAutoCloseConnection; this.context.CurrentConnectionConfig.IsAutoCloseConnection = false; dataTable.TableName = this.queryable.SqlBuilder.GetTranslationTableName(tableName); - DataTable dt = GetCopyWriteDataTable(dataTable); + DataTable dt = GetCopyWriteDataTableUpdate(dataTable); IFastBuilder buider = GetBuider(); if (dt.Columns.Count != dataTable.Columns.Count) { diff --git a/Src/Asp.NetCore2/SqlSugar/Abstract/FastestProvider/Private.cs b/Src/Asp.NetCore2/SqlSugar/Abstract/FastestProvider/Private.cs index 324f87b18..a68bd3f40 100644 --- a/Src/Asp.NetCore2/SqlSugar/Abstract/FastestProvider/Private.cs +++ b/Src/Asp.NetCore2/SqlSugar/Abstract/FastestProvider/Private.cs @@ -212,7 +212,53 @@ namespace SqlSugar tempDataTable.TableName = dt.TableName; return tempDataTable; } + private DataTable GetCopyWriteDataTableUpdate(DataTable dt) + { + var sqlBuilder = this.context.Queryable().SqlBuilder; + var dts = dt.Columns.Cast().Select(it => sqlBuilder.GetTranslationColumnName(it.ColumnName)).ToList(); + DataTable tempDataTable = null; + if (AsName == null) + { + tempDataTable = queryable.Where(it => false).Select(string.Join(",", dts)).ToDataTable(); + } + else + { + tempDataTable = queryable.AS(AsName).Where(it => false).Select(string.Join(",", dts)).ToDataTable(); + }; + List uInt64TypeName = new List(); + foreach (DataColumn item in tempDataTable.Columns) + { + if (item.DataType == typeof(UInt64)) + { + uInt64TypeName.Add(item.ColumnName); + } + } + var temColumnsList = tempDataTable.Columns.Cast().Select(it => it.ColumnName.ToLower()).ToList(); + var columns = dt.Columns.Cast().Where(it => temColumnsList.Contains(it.ColumnName.ToLower())).ToList(); + foreach (DataRow item in dt.Rows) + { + DataRow dr = tempDataTable.NewRow(); + foreach (DataColumn column in columns) + { + dr[column.ColumnName] = item[column.ColumnName]; + if (dr[column.ColumnName] == null || dr[column.ColumnName] == DBNull.Value) + { + dr[column.ColumnName] = DBNull.Value; + } + else if (column.DataType == UtilConstants.BoolType && this.context.CurrentConnectionConfig.DbType.IsIn(DbType.MySql, DbType.MySqlConnector)) + { + if (Convert.ToBoolean(dr[column.ColumnName]) == false && uInt64TypeName.Any(z => z.EqualCase(column.ColumnName))) + { + dr[column.ColumnName] = DBNull.Value; + } + } + } + tempDataTable.Rows.Add(dr); + } + tempDataTable.TableName = dt.TableName; + return tempDataTable; + } private void RemoveCache() { diff --git a/Src/Asp.NetCore2/SqlSugar/Realization/Oracle/SqlBuilder/OracleFastBuilder.cs b/Src/Asp.NetCore2/SqlSugar/Realization/Oracle/SqlBuilder/OracleFastBuilder.cs index 136c66e71..944c9a057 100644 --- a/Src/Asp.NetCore2/SqlSugar/Realization/Oracle/SqlBuilder/OracleFastBuilder.cs +++ b/Src/Asp.NetCore2/SqlSugar/Realization/Oracle/SqlBuilder/OracleFastBuilder.cs @@ -1,12 +1,10 @@ using Oracle.ManagedDataAccess.Client; using System; -using System.Collections.Generic; using System.Data; using System.Linq; -using System.Text; using System.Threading.Tasks; -namespace SqlSugar +namespace SqlSugar { public class OracleFastBuilder : FastBuilder, IFastBuilder { @@ -20,17 +18,28 @@ namespace SqlSugar public override string UpdateSql { get; set; } = "UPDATE (SELECT {4} FROM {2} TM,{3} TE WHERE {1})SET {0}"; public override async Task CreateTempAsync(DataTable dt) { + var sqlBuilder = this.Context.Queryable().SqlBuilder; + var dts = dt.Columns.Cast().Select(it => sqlBuilder.GetTranslationColumnName(it.ColumnName)).ToList(); //await Task.FromResult(0); //throw new Exception("Oracle no support BulkUpdate"); var oldTableName = dt.TableName; - var columns = this.Context.EntityMaintenance.GetEntityInfo().Columns.Where(it => it.IsPrimarykey).Select(it => it.DbColumnName).ToArray(); + var columns = this.Context.EntityMaintenance.GetEntityInfo().Columns.Where(it => it.IsPrimarykey).Select(it => it.DbColumnName).ToList(); dt.TableName = "Temp" + SnowFlakeSingle.instance.getID().ToString(); - var sql = this.Context.Queryable().AS(oldTableName).Where(it => false).Select("*").ToSql().Key; - await this.Context.Ado.ExecuteCommandAsync($"create table {dt.TableName} as {sql} "); - if (columns != null && columns.Any()) + if (columns.Count() == 0) { - this.Context.DbMaintenance.AddPrimaryKeys(dt.TableName, columns, "Pk_" + SnowFlakeSingle.instance.getID().ToString()); + var pkColumn = sqlBuilder.GetTranslationColumnName("sys_guid_Id"); + var pkColumnName = sqlBuilder.GetNoTranslationColumnName( sqlBuilder.GetTranslationColumnName("sys_guid_Id")); + dts.Add("sys_guid() as " + pkColumn); + dt.Columns.Add(pkColumnName,typeof(Guid)); + columns.Add(pkColumnName); + foreach (DataRow item in dt.Rows) + { + item[pkColumnName] = Guid.NewGuid(); + } } + var sql = this.Context.Queryable().AS(oldTableName).Where(it => false).Select(string.Join(",", dts)).ToSql().Key; + await this.Context.Ado.ExecuteCommandAsync($"create table {dt.TableName} as {sql} "); + this.Context.DbMaintenance.AddPrimaryKeys(dt.TableName, columns.ToArray(), "Pk_" + SnowFlakeSingle.instance.getID().ToString()); } public override async Task UpdateByTempAsync(string tableName, string tempName, string[] updateColumns, string[] whereColumns) { @@ -39,8 +48,8 @@ namespace SqlSugar Check.ArgumentNullException(!whereColumns.Any(), "where columns count is 0"); var sets = string.Join(",", updateColumns.Select(it => $"TM{it}=TE{it}")); var wheres = string.Join(" AND ", whereColumns.Select(it => $"TM.{sqlBuilder.GetTranslationColumnName(it)}=TE.{sqlBuilder.GetTranslationColumnName(it)}")); - var forms= string.Join(",", updateColumns.Select(it => $" TM.{sqlBuilder.GetTranslationColumnName(it)} TM{it},TE.{sqlBuilder.GetTranslationColumnName(it)} TE{it}")); ; - string sql = string.Format(UpdateSql, sets, wheres,tableName, tempName, forms); + var forms = string.Join(",", updateColumns.Select(it => $" TM.{sqlBuilder.GetTranslationColumnName(it)} TM{it},TE.{sqlBuilder.GetTranslationColumnName(it)} TE{it}")); ; + string sql = string.Format(UpdateSql, sets, wheres, tableName, tempName, forms); return await this.Context.Ado.ExecuteCommandAsync(sql); } private OracleBulkCopy GetBulkCopyInstance() @@ -81,7 +90,7 @@ namespace SqlSugar { throw ex; } - finally + finally { CloseDb(); }