diff --git a/Src/Asp.Net/SqlSugar/Abstract/FastestProvider/FastestProvider.cs b/Src/Asp.Net/SqlSugar/Abstract/FastestProvider/FastestProvider.cs new file mode 100644 index 000000000..d7b9b40b0 --- /dev/null +++ b/Src/Asp.Net/SqlSugar/Abstract/FastestProvider/FastestProvider.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Text; +using System.Threading.Tasks; + +namespace SqlSugar +{ + public class FastestProvider:IFastest + { + private SqlSugarProvider context; + private ISugarQueryable queryable; + + public FastestProvider(SqlSugarProvider sqlSugarProvider) + { + this.context = sqlSugarProvider; + this.queryable = this.context.Queryable(); + } + public int BulkCopy(List datas) + { + return BulkCopyAsync(datas).GetAwaiter().GetResult(); + } + public async Task BulkCopyAsync(List datas) + { + + DataTable tempDataTable = ReflectionInoCore.GetInstance().GetOrCreate("BulkCopyAsync" + typeof(T).FullName,()=> queryable.Where(it=>false).ToDataTable()); + var dt = new DataTable(); + foreach (DataColumn item in tempDataTable.Columns) + { + dt.Columns.Add(item.ColumnName,item.DataType); + } + var entityInfo = this.context.EntityMaintenance.GetEntityInfo(); + dt.TableName =queryable.SqlBuilder.GetTranslationTableName(entityInfo.DbTableName); + var columns = entityInfo.Columns; + foreach (var item in datas) + { + var dr = dt.NewRow(); + foreach (var column in columns) + { + if (column.IsIgnore || column.IsOnlyIgnoreInsert) + { + continue; + } + var name = column.DbColumnName; + if (name == null) + { + name = column.PropertyName; + } + var value = ValueConverter(column, PropertyCallAdapterProvider.GetInstance(column.PropertyName).InvokeGet(item)); + dr[name] = value; + } + dt.Rows.Add(dr); + } + IFastBuilder buider = new SqlServerFastBuilder(); + buider.Context = context; + var result= await buider.ExecuteBulkCopyAsync(dt); + return result; + } + + private object ValueConverter(EntityColumnInfo columnInfo,object value) + { + if (value == null) + return value; + if (value is DateTime&&(DateTime)value == DateTime.MinValue) + { + value = Convert.ToDateTime("1900-01-01"); + } + return value; + } + } +} diff --git a/Src/Asp.Net/SqlSugar/Abstract/SugarProvider/SqlSugarProvider.cs b/Src/Asp.Net/SqlSugar/Abstract/SugarProvider/SqlSugarProvider.cs index eae1f92b6..ab458706d 100644 --- a/Src/Asp.Net/SqlSugar/Abstract/SugarProvider/SqlSugarProvider.cs +++ b/Src/Asp.Net/SqlSugar/Abstract/SugarProvider/SqlSugarProvider.cs @@ -1175,7 +1175,13 @@ namespace SqlSugar Check.Exception(true,ErrorMessage.GetThrowMessage("Child objects do not support tenant methods, var childDb= Db.GetConnection(confid) ,Db is master ", "Db子对象不支持租户方法,请使用主对象,例如:var childDb= Db.GetConnection(confid) Db是主对象,childDb是子对象 ")); return null; } - #endregion + #endregion + #region + public IFastest Fastest() + { + return new FastestProvider(this); + } + #endregion } } diff --git a/Src/Asp.Net/SqlSugar/Interface/IFastBuilder.cs b/Src/Asp.Net/SqlSugar/Interface/IFastBuilder.cs new file mode 100644 index 000000000..6a9948411 --- /dev/null +++ b/Src/Asp.Net/SqlSugar/Interface/IFastBuilder.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SqlSugar +{ + public interface IFastBuilder + { + SqlSugarProvider Context { get; set; } + + Task ExecuteBulkCopyAsync(DataTable dt); + } +} diff --git a/Src/Asp.Net/SqlSugar/Interface/IFastest.cs b/Src/Asp.Net/SqlSugar/Interface/IFastest.cs new file mode 100644 index 000000000..5c62a45e9 --- /dev/null +++ b/Src/Asp.Net/SqlSugar/Interface/IFastest.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +namespace SqlSugar +{ + public interface IFastest + { + int BulkCopy(List datas); + Task BulkCopyAsync(List datas); + } +} diff --git a/Src/Asp.Net/SqlSugar/Interface/ISqlSugarClient.cs b/Src/Asp.Net/SqlSugar/Interface/ISqlSugarClient.cs index df631a1e2..c0ec0a4d4 100644 --- a/Src/Asp.Net/SqlSugar/Interface/ISqlSugarClient.cs +++ b/Src/Asp.Net/SqlSugar/Interface/ISqlSugarClient.cs @@ -176,5 +176,10 @@ namespace SqlSugar #region Cache SugarCacheProvider DataCache { get; } #endregion + + #region Fastest + IFastest Fastest(); + #endregion + } } \ No newline at end of file diff --git a/Src/Asp.Net/SqlSugar/Realization/SqlServer/SqlBuilder/SqlServerFastBuilder.cs b/Src/Asp.Net/SqlSugar/Realization/SqlServer/SqlBuilder/SqlServerFastBuilder.cs new file mode 100644 index 000000000..31b42ff08 --- /dev/null +++ b/Src/Asp.Net/SqlSugar/Realization/SqlServer/SqlBuilder/SqlServerFastBuilder.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.SqlClient; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SqlSugar +{ + public class SqlServerFastBuilder: IFastBuilder + { + + public SqlSugarProvider Context { get; set; } + + + public async Task ExecuteBulkCopyAsync(DataTable dt) + { + + SqlBulkCopy bulkCopy = GetBulkCopyInstance(); + bulkCopy.DestinationTableName = dt.TableName; + try + { + await bulkCopy.WriteToServerAsync(dt); + } + catch (Exception ex) + { + CloseDb(); + throw ex; + } + CloseDb(); + return dt.Rows.Count; + } + public SqlBulkCopy GetBulkCopyInstance() + { + SqlBulkCopy copy; + if (this.Context.Ado.Transaction == null) + { + copy = new SqlBulkCopy((SqlConnection)this.Context.Ado.Connection); + } + else + { + copy = new SqlBulkCopy((SqlConnection)this.Context.Ado.Connection, SqlBulkCopyOptions.CheckConstraints, (SqlTransaction)this.Context.Ado.Transaction); + } + if (this.Context.Ado.Connection.State == ConnectionState.Closed) + { + this.Context.Ado.Connection.Open(); + } + return copy; + } + public void CloseDb() + { + if (this.Context.CurrentConnectionConfig.IsAutoCloseConnection && this.Context.Ado.Transaction == null) + { + this.Context.Ado.Connection.Close(); + } + } + } +} diff --git a/Src/Asp.Net/SqlSugar/SqlSugar.csproj b/Src/Asp.Net/SqlSugar/SqlSugar.csproj index 38b422f7a..2ddfb472d 100644 --- a/Src/Asp.Net/SqlSugar/SqlSugar.csproj +++ b/Src/Asp.Net/SqlSugar/SqlSugar.csproj @@ -88,7 +88,11 @@ + + + + diff --git a/Src/Asp.Net/SqlSugar/SqlSugarClient.cs b/Src/Asp.Net/SqlSugar/SqlSugarClient.cs index 456c53c97..69e5c7d1e 100644 --- a/Src/Asp.Net/SqlSugar/SqlSugarClient.cs +++ b/Src/Asp.Net/SqlSugar/SqlSugarClient.cs @@ -565,6 +565,13 @@ namespace SqlSugar #endregion + #region + public IFastest Fastest() + { + return this.Context.Fastest(); + } + #endregion + #region More api public IContextMethods Utilities { get { return this.Context.Utilities; } set { this.Context.Utilities = value; } } public AopProvider Aop => this.Context.Aop; diff --git a/Src/Asp.Net/SqlSugar/SqlSugarScope.cs b/Src/Asp.Net/SqlSugar/SqlSugarScope.cs index 32a45b810..ffe3fd1e3 100644 --- a/Src/Asp.Net/SqlSugar/SqlSugarScope.cs +++ b/Src/Asp.Net/SqlSugar/SqlSugarScope.cs @@ -641,6 +641,10 @@ namespace SqlSugar return ScopedContext.IsAnyConnection(configId); } + public IFastest Fastest() + { + return ScopedContext.Fastest(); + } private SqlSugarClient GetContext() { SqlSugarClient result = null;