SqlServerFastBuilder.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. using Microsoft.Data.SqlClient;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Data;
  5. using System.Data.SqlClient;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. namespace SqlSugar
  10. {
  11. public class SqlServerFastBuilder:FastBuilder,IFastBuilder
  12. {
  13. public override bool IsActionUpdateColumns { get; set; } = true;
  14. public override DbFastestProperties DbFastestProperties { get; set; } = new DbFastestProperties() {
  15. HasOffsetTime=true,
  16. IsMerge=true
  17. };
  18. public async Task<int> ExecuteBulkCopyAsync(DataTable dt)
  19. {
  20. SqlBulkCopy bulkCopy = GetBulkCopyInstance();
  21. bulkCopy.DestinationTableName = dt.TableName;
  22. try
  23. {
  24. await bulkCopy.WriteToServerAsync(dt);
  25. }
  26. catch (Exception ex)
  27. {
  28. CloseDb();
  29. throw ex;
  30. }
  31. CloseDb();
  32. return dt.Rows.Count;
  33. }
  34. public SqlBulkCopy GetBulkCopyInstance()
  35. {
  36. SqlBulkCopy copy;
  37. if (this.Context.Ado.Transaction == null)
  38. {
  39. if (this.DbFastestProperties?.IsOffIdentity == true)
  40. {
  41. copy = new SqlBulkCopy((SqlConnection)this.Context.Ado.Connection, SqlBulkCopyOptions.KeepIdentity,null);
  42. }
  43. else
  44. {
  45. copy = new SqlBulkCopy((SqlConnection)this.Context.Ado.Connection);
  46. }
  47. }
  48. else
  49. {
  50. if (this.DbFastestProperties?.IsOffIdentity == true)
  51. {
  52. copy = new SqlBulkCopy((SqlConnection)this.Context.Ado.Connection, SqlBulkCopyOptions.KeepIdentity, (SqlTransaction)this.Context.Ado.Transaction);
  53. }
  54. else
  55. {
  56. copy = new SqlBulkCopy((SqlConnection)this.Context.Ado.Connection, SqlBulkCopyOptions.CheckConstraints, (SqlTransaction)this.Context.Ado.Transaction);
  57. }
  58. }
  59. if (this.Context.Ado.Connection.State == ConnectionState.Closed)
  60. {
  61. this.Context.Ado.Connection.Open();
  62. }
  63. copy.BulkCopyTimeout = this.Context.Ado.CommandTimeOut;
  64. return copy;
  65. }
  66. public override Task<int> Merge<T>(string tableName,DataTable dt, EntityInfo entityInfo, string[] whereColumns, string[] updateColumns, List<T> datas)
  67. {
  68. var sqlBuilder = this.Context.Queryable<object>().SqlBuilder;
  69. var insertColumns = entityInfo.Columns
  70. .Where(it => it.IsIgnore == false)
  71. .Where(it => it.IsIdentity == false)
  72. .Where(it => it.OracleSequenceName == null)
  73. .Where(it => it.InsertServerTime == false)
  74. .Where(it => it.InsertSql == null)
  75. .Where(it => it.IsOnlyIgnoreInsert == false);
  76. var whereSql = string.Join(" AND ", whereColumns.Select(it => $"tgt.{sqlBuilder.GetTranslationColumnName(it)}=src.{sqlBuilder.GetTranslationColumnName(it)}"));
  77. var updateColumnsSql = string.Join(" , ", updateColumns.Select(it => $"tgt.{sqlBuilder.GetTranslationColumnName(it)}=src.{sqlBuilder.GetTranslationColumnName(it)}"));
  78. var insertColumnsSqlTgt = string.Join(" , ", insertColumns.Select(it => sqlBuilder.GetTranslationColumnName(it.DbColumnName)));
  79. var insertColumnsSqlsrc = string.Join(" , ", insertColumns.Select(it => "src." + sqlBuilder.GetTranslationColumnName(it.DbColumnName)));
  80. var sql = $@"MERGE INTO {sqlBuilder.GetTranslationColumnName(tableName)} tgt
  81. USING {sqlBuilder.GetTranslationColumnName(dt.TableName)} src
  82. ON ({whereSql})
  83. WHEN MATCHED THEN
  84. UPDATE SET {updateColumnsSql}
  85. WHEN NOT MATCHED THEN
  86. INSERT ({insertColumnsSqlTgt})
  87. VALUES ({insertColumnsSqlsrc});";
  88. return this.Context.Ado.ExecuteCommandAsync(sql);
  89. }
  90. }
  91. }