OracleBlukCopy.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data;
  4. using Oracle.ManagedDataAccess.Client;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. namespace SqlSugar
  9. {
  10. public class OracleBlukCopy
  11. {
  12. internal List<IGrouping<int, DbColumnInfo>> DbColumnInfoList { get; set; }
  13. internal SqlSugarProvider Context { get; set; }
  14. internal ISqlBuilder Builder { get; set; }
  15. internal InsertBuilder InsertBuilder { get; set; }
  16. internal object[] Inserts { get; set; }
  17. public int ExecuteBulkCopy()
  18. {
  19. if (DbColumnInfoList == null || DbColumnInfoList.Count == 0) return 0;
  20. if (Inserts.First().GetType() == typeof(DataTable))
  21. {
  22. return WriteToServer();
  23. }
  24. DataTable dt = GetCopyData();
  25. OracleBulkCopy bulkCopy = GetBulkCopyInstance();
  26. bulkCopy.DestinationTableName = InsertBuilder.GetTableNameString;
  27. try
  28. {
  29. bulkCopy.WriteToServer(dt);
  30. }
  31. catch (Exception ex)
  32. {
  33. CloseDb();
  34. throw ex;
  35. }
  36. CloseDb();
  37. return DbColumnInfoList.Count;
  38. }
  39. public async Task<int> ExecuteBulkCopyAsync()
  40. {
  41. if (DbColumnInfoList == null || DbColumnInfoList.Count == 0) return 0;
  42. if (Inserts.First().GetType() == typeof(DataTable))
  43. {
  44. return WriteToServer();
  45. }
  46. DataTable dt = GetCopyData();
  47. OracleBulkCopy bulkCopy = GetBulkCopyInstance();
  48. bulkCopy.DestinationTableName = InsertBuilder.GetTableNameString;
  49. try
  50. {
  51. await Task.Run(() => bulkCopy.WriteToServer(dt));
  52. }
  53. catch (Exception ex)
  54. {
  55. CloseDb();
  56. throw ex;
  57. }
  58. CloseDb();
  59. return DbColumnInfoList.Count;
  60. }
  61. private int WriteToServer()
  62. {
  63. var dt = this.Inserts.First() as DataTable;
  64. if (dt == null)
  65. return 0;
  66. Check.Exception(dt.TableName == "Table", "dt.TableName can't be null ");
  67. dt = GetCopyWriteDataTable(dt);
  68. OracleBulkCopy copy = GetBulkCopyInstance();
  69. copy.DestinationTableName = this.Builder.GetTranslationColumnName(dt.TableName);
  70. copy.WriteToServer(dt);
  71. CloseDb();
  72. return dt.Rows.Count;
  73. }
  74. private DataTable GetCopyWriteDataTable(DataTable dt)
  75. {
  76. var result = this.Context.Ado.GetDataTable("select * from " + this.Builder.GetTranslationColumnName(dt.TableName) + " where 1 > 2 ");
  77. foreach (DataRow item in dt.Rows)
  78. {
  79. DataRow dr = result.NewRow();
  80. foreach (DataColumn column in result.Columns)
  81. {
  82. if (dt.Columns.Cast<DataColumn>().Select(it => it.ColumnName.ToLower()).Contains(column.ColumnName.ToLower()))
  83. {
  84. dr[column.ColumnName] = item[column.ColumnName];
  85. if (dr[column.ColumnName] == null)
  86. {
  87. dr[column.ColumnName] = DBNull.Value;
  88. }
  89. }
  90. }
  91. result.Rows.Add(dr);
  92. }
  93. result.TableName = dt.TableName;
  94. return result;
  95. }
  96. private OracleBulkCopy GetBulkCopyInstance()
  97. {
  98. if (this.Context.Ado.Connection.State == ConnectionState.Closed)
  99. {
  100. this.Context.Ado.Connection.Open();
  101. }
  102. OracleBulkCopy copy;
  103. if (this.Context.Ado.Transaction == null)
  104. {
  105. copy = new OracleBulkCopy((OracleConnection)this.Context.Ado.Connection, Oracle.ManagedDataAccess.Client.OracleBulkCopyOptions.Default);
  106. }
  107. else
  108. {
  109. copy = new OracleBulkCopy((OracleConnection)this.Context.Ado.Connection, OracleBulkCopyOptions.UseInternalTransaction);
  110. }
  111. return copy;
  112. }
  113. private DataTable GetCopyData()
  114. {
  115. var dt = this.Context.Ado.GetDataTable("select * from " + InsertBuilder.GetTableNameString + " where 1 > 2 ");
  116. foreach (var rowInfos in DbColumnInfoList)
  117. {
  118. var dr = dt.NewRow();
  119. foreach (DataColumn item in dt.Columns)
  120. {
  121. var rows = rowInfos.ToList();
  122. var value = rows.FirstOrDefault(it =>
  123. it.DbColumnName.Equals(item.ColumnName, StringComparison.CurrentCultureIgnoreCase) ||
  124. it.PropertyName.Equals(item.ColumnName, StringComparison.CurrentCultureIgnoreCase)
  125. );
  126. if (value != null)
  127. {
  128. if (value.Value != null && UtilMethods.GetUnderType(value.Value.GetType()) == UtilConstants.DateType)
  129. {
  130. if (value.Value != null && value.Value.ToString() == DateTime.MinValue.ToString())
  131. {
  132. value.Value = Convert.ToDateTime("1900/01/01");
  133. }
  134. }
  135. if (value.Value == null)
  136. {
  137. value.Value = DBNull.Value;
  138. }
  139. dr[item.ColumnName] = value.Value;
  140. }
  141. }
  142. dt.Rows.Add(dr);
  143. }
  144. if (this.InsertBuilder.OracleSeqInfoList != null && this.InsertBuilder.OracleSeqInfoList.Any())
  145. {
  146. var ids = this.InsertBuilder.OracleSeqInfoList.Select(it => it.Value).ToList();
  147. var columnInfo = this.InsertBuilder.EntityInfo.Columns.Where(it => !string.IsNullOrEmpty(it.OracleSequenceName)).First();
  148. var identityName = columnInfo.DbColumnName;
  149. ids.Add(this.Context.Ado.GetInt(" select " + columnInfo.OracleSequenceName + ".nextval from dual"));
  150. int i = 0;
  151. foreach (DataRow item in dt.Rows)
  152. {
  153. item[identityName] = ids[i];
  154. ++i;
  155. }
  156. }
  157. return dt;
  158. }
  159. private void CloseDb()
  160. {
  161. if (this.Context.CurrentConnectionConfig.IsAutoCloseConnection && this.Context.Ado.Transaction == null)
  162. {
  163. this.Context.Ado.Connection.Close();
  164. }
  165. }
  166. }
  167. }