diff --git a/Src/Asp.NetCore2/SqlSugar/Abstract/FastestProvider/FastBuilder.cs b/Src/Asp.NetCore2/SqlSugar/Abstract/FastestProvider/FastBuilder.cs index ea3157e5c..cb9a937c7 100644 --- a/Src/Asp.NetCore2/SqlSugar/Abstract/FastestProvider/FastBuilder.cs +++ b/Src/Asp.NetCore2/SqlSugar/Abstract/FastestProvider/FastBuilder.cs @@ -9,6 +9,7 @@ namespace SqlSugar { public class FastBuilder { + public EntityInfo FastEntityInfo { get; set; } public virtual bool IsActionUpdateColumns { get; set; } public virtual DbFastestProperties DbFastestProperties { get; set; } public SqlSugarProvider Context { get; set; } diff --git a/Src/Asp.NetCore2/SqlSugar/Abstract/FastestProvider/Private.cs b/Src/Asp.NetCore2/SqlSugar/Abstract/FastestProvider/Private.cs index cd17ac89c..4d98df1ce 100644 --- a/Src/Asp.NetCore2/SqlSugar/Abstract/FastestProvider/Private.cs +++ b/Src/Asp.NetCore2/SqlSugar/Abstract/FastestProvider/Private.cs @@ -42,7 +42,10 @@ namespace SqlSugar default: break; } - throw new Exception(this.context.CurrentConnectionConfig.DbType + "开发中..."); + var reslut = InstanceFactory.CreateInstance($"SqlSugar.{this.context.CurrentConnectionConfig.DbType}FastBuilder"); + reslut.CharacterSet = this.CharacterSet; + reslut.FastEntityInfo = this.entityInfo; + return reslut; } private DataTable ToDdateTable(List datas) { diff --git a/Src/Asp.NetCore2/SqlSugar/Interface/IFastBuilder.cs b/Src/Asp.NetCore2/SqlSugar/Interface/IFastBuilder.cs index 8a5db2035..1b6c7c71a 100644 --- a/Src/Asp.NetCore2/SqlSugar/Interface/IFastBuilder.cs +++ b/Src/Asp.NetCore2/SqlSugar/Interface/IFastBuilder.cs @@ -9,6 +9,7 @@ namespace SqlSugar { public interface IFastBuilder { + EntityInfo FastEntityInfo { get; set; } bool IsActionUpdateColumns { get; set; } DbFastestProperties DbFastestProperties { get; set; } SqlSugarProvider Context { get; set; } diff --git a/Src/Asp.NetCore2/SqlSugar/Realization/Kdbndp/SqlBuilder/KdbndpFastBuilder.cs b/Src/Asp.NetCore2/SqlSugar/Realization/Kdbndp/SqlBuilder/KdbndpFastBuilder.cs new file mode 100644 index 000000000..33489c261 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar/Realization/Kdbndp/SqlBuilder/KdbndpFastBuilder.cs @@ -0,0 +1,144 @@ +using Npgsql; +using NpgsqlTypes; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SqlSugar +{ + public class KdbndpFastBuilder : FastBuilder, IFastBuilder + { + public static Dictionary PgSqlType = UtilMethods.EnumToDictionary(); + + public KdbndpFastBuilder() + { + } + + public override string UpdateSql { get; set; } = @"UPDATE {1} SET {0} FROM {2} AS TE WHERE {3} +"; + + //public virtual async Task UpdateByTempAsync(string tableName, string tempName, string[] updateColumns, string[] whereColumns) + //{ + // Check.ArgumentNullException(!updateColumns.Any(), "update columns count is 0"); + // Check.ArgumentNullException(!whereColumns.Any(), "where columns count is 0"); + // var sets = string.Join(",", updateColumns.Select(it => $"TM.{it}=TE.{it}")); + // var wheres = string.Join(",", whereColumns.Select(it => $"TM.{it}=TE.{it}")); + // string sql = string.Format(UpdateSql, sets, tableName, tempName, wheres); + // return await this.Context.Ado.ExecuteCommandAsync(sql); + //} + public async Task ExecuteBulkCopyAsync(DataTable dt) + { + List lsColNames = new List(); + for (int i = 0; i < dt.Columns.Count; i++) + { + lsColNames.Add($"\"{dt.Columns[i].ColumnName}\""); + } + string copyString = $"COPY {dt.TableName} ( {string.Join(",", lsColNames) } ) FROM STDIN (FORMAT BINARY)"; + Kdbndp.KdbndpConnection conn = (Kdbndp.KdbndpConnection)this.Context.Ado.Connection; + var columns = this.Context.DbMaintenance.GetColumnInfosByTableName(this.FastEntityInfo.DbTableName); + try + { + var identityColumnInfo = this.FastEntityInfo.Columns.FirstOrDefault(it => it.IsIdentity); + if (identityColumnInfo != null) + { + throw new Exception("PgSql bulkcopy no support identity"); + } + BulkCopy(dt, copyString, conn, columns); + } + catch (Exception ex) + { + throw ex; + } + finally + { + base.CloseDb(); + } + return await Task.FromResult(dt.Rows.Count); + } + + private void BulkCopy(DataTable dt, string copyString, Kdbndp.KdbndpConnection conn, List columns) + { + if (conn.State == ConnectionState.Closed) + conn.Open(); + List columnViews = new List(); + foreach (DataColumn item in dt.Columns) + { + ColumnView result = new ColumnView(); + result.DbColumnInfo = columns.FirstOrDefault(it => it.DbColumnName.EqualCase(item.ColumnName)); + result.DataColumn = item; + result.EntityColumnInfo=this.FastEntityInfo.Columns.FirstOrDefault(it => it.DbColumnName.EqualCase(item.ColumnName)); + var key = result.DbColumnInfo?.DataType?.ToLower(); + if (result.DbColumnInfo == null) + { + result.Type = null; + } + else if (PgSqlType.ContainsKey(key)) + { + result.Type = PgSqlType[key]; + } + else if (key?.First() == '_') + { + var type = PgSqlType[key.Substring(1)]; + result.Type = NpgsqlDbType.Array | type; + } + else + { + result.Type = null; + } + columnViews.Add(result); + } + using (var writer = conn.BeginBinaryImport(copyString)) + { + foreach (DataRow row in dt.Rows) + { + writer.StartRow(); + foreach (var column in columnViews) + { + var value = row[column.DataColumn.ColumnName]; + if (value == null) + { + value = DBNull.Value; + } + if (column.Type == null) + { + writer.Write(value); + } + else + { + writer.Write(value); + } + } + } + writer.Complete(); + } + } + + + public override async Task UpdateByTempAsync(string tableName, string tempName, string[] updateColumns, string[] whereColumns) + { + var sqlquerybulder= this.Context.Queryable().SqlBuilder; + Check.ArgumentNullException(!updateColumns.Any(), "update columns count is 0"); + Check.ArgumentNullException(!whereColumns.Any(), "where columns count is 0"); + var sets = string.Join(",", updateColumns.Select(it => $"{sqlquerybulder.GetTranslationColumnName(it)}=TE.{sqlquerybulder.GetTranslationColumnName(it)}")); + var wheres = string.Join(" AND ", whereColumns.Select(it => $"{tableName}.{sqlquerybulder.GetTranslationColumnName(it)}=TE.{sqlquerybulder.GetTranslationColumnName(it)}")); + string sql = string.Format(UpdateSql, sets, tableName, tempName, wheres); + return await this.Context.Ado.ExecuteCommandAsync(sql); + } + public override async Task CreateTempAsync(DataTable dt) + { + await this.Context.Queryable().Where(it => false).AS(dt.TableName).Select(" * into temp mytemptable").ToListAsync(); + dt.TableName = "mytemptable"; + } + + public class ColumnView + { + public DataColumn DataColumn { get; set; } + public EntityColumnInfo EntityColumnInfo { get; set; } + public DbColumnInfo DbColumnInfo { get; set; } + public NpgsqlDbType? Type { get; set; } + } + } +} diff --git a/Src/Asp.NetCore2/SqlSugar/Realization/Sqlite/SqlBuilder/SqliteFastBuilder.cs b/Src/Asp.NetCore2/SqlSugar/Realization/Sqlite/SqlBuilder/SqliteFastBuilder.cs index 2e7f155c7..ff503fc5f 100644 --- a/Src/Asp.NetCore2/SqlSugar/Realization/Sqlite/SqlBuilder/SqliteFastBuilder.cs +++ b/Src/Asp.NetCore2/SqlSugar/Realization/Sqlite/SqlBuilder/SqliteFastBuilder.cs @@ -10,6 +10,7 @@ namespace SqlSugar { public class SqliteFastBuilder : IFastBuilder { + public EntityInfo FastEntityInfo { get; set; } private EntityInfo entityInfo; private bool IsUpdate = false; public string CharacterSet { get; set; }