MySqlFastBuilder.cs 4.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. using MySqlConnector;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Data;
  5. using System.Data.SqlClient;
  6. using System.IO;
  7. using System.Linq;
  8. using System.Text;
  9. using System.Threading.Tasks;
  10. namespace SqlSugar
  11. {
  12. public partial class MySqlFastBuilder:FastBuilder,IFastBuilder
  13. {
  14. public override string UpdateSql { get; set; } = @"UPDATE {1} TM INNER JOIN {2} TE ON {3} SET {0} ";
  15. public async Task<int> ExecuteBulkCopyAsync(DataTable dt)
  16. {
  17. if (dt.Columns.Cast<DataColumn>().Any(it => it.DataType == UtilConstants.ByteArrayType))
  18. {
  19. return await MySqlConnectorBulkCopy(dt);
  20. }
  21. var dllPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bulkcopyfiles");
  22. DirectoryInfo dir = new DirectoryInfo(dllPath);
  23. if (!dir.Exists)
  24. {
  25. dir.Create();
  26. }
  27. var fileName = Path.Combine(dllPath, Guid.NewGuid().ToString() + ".csv");
  28. var dataTableToCsv =new MySqlBlukCopy<object>(this.Context.Context,null,null).DataTableToCsvString(dt);
  29. File.WriteAllText(fileName, dataTableToCsv, new UTF8Encoding(false));
  30. MySqlConnection conn = this.Context.Ado.Connection as MySqlConnection;
  31. int result = 0;
  32. try
  33. {
  34. this.Context.Ado.Open();
  35. // IsolationLevel.Parse
  36. MySqlBulkLoader bulk = new MySqlBulkLoader(conn)
  37. {
  38. CharacterSet = "utf8mb4",
  39. FieldTerminator = ",",
  40. FieldQuotationCharacter = '"',
  41. EscapeCharacter = '"',
  42. LineTerminator = Environment.NewLine,
  43. FileName = fileName,
  44. NumberOfLinesToSkip = 0,
  45. TableName = dt.TableName,
  46. Local = true,
  47. };
  48. if (this.CharacterSet.HasValue())
  49. {
  50. bulk.CharacterSet = this.CharacterSet;
  51. }
  52. bulk.Columns.AddRange(dt.Columns.Cast<DataColumn>().Select(colum =>new MySqlBuilder().GetTranslationColumnName(colum.ColumnName)).Distinct().ToArray());
  53. result= await bulk.LoadAsync();
  54. //执行成功才删除文件
  55. if (File.Exists(fileName))
  56. {
  57. File.Delete(fileName);
  58. }
  59. }
  60. catch (Exception ex)
  61. {
  62. if (ex.Message == "The used command is not allowed with this MySQL version")
  63. {
  64. Check.ExceptionEasy("connection string add : AllowLoadLocalInfile=true", "BulkCopy MySql连接字符串需要添加 AllowLoadLocalInfile=true; 添加后如果还不行Mysql数据库执行一下 SET GLOBAL local_infile=1 ");
  65. }
  66. else if (ex.Message.Contains("To use MySqlBulkLoader.Local=true, set Allo"))
  67. {
  68. Check.ExceptionEasy("connection string add : AllowLoadLocalInfile=true", "BulkCopy MySql连接字符串需要添加 AllowLoadLocalInfile=true; 添加后如果还不行Mysql数据库执行一下 SET GLOBAL local_infile=1 ");
  69. }
  70. else if (ex.Message == "Loading local data is disabled; this must be enabled on both the client and server sides")
  71. {
  72. this.Context.Ado.ExecuteCommand("SET GLOBAL local_infile=1");
  73. Check.ExceptionEasy(ex.Message, " 检测到你没有开启文件,AllowLoadLocalInfile=true加到自符串上,已自动执行 SET GLOBAL local_infile=1 在试一次");
  74. }
  75. else
  76. {
  77. throw;
  78. }
  79. }
  80. finally
  81. {
  82. CloseDb();
  83. }
  84. return result;
  85. }
  86. public override async Task CreateTempAsync<T>(DataTable dt)
  87. {
  88. var queryable = this.Context.Queryable<T>();
  89. var tableName = queryable.SqlBuilder.GetTranslationTableName(dt.TableName);
  90. dt.TableName = "temp"+SnowFlakeSingle.instance.getID();
  91. var sql = queryable.AS(tableName).Where(it => false).ToSql().Key;
  92. await this.Context.Ado.ExecuteCommandAsync($"Create TEMPORARY table {dt.TableName}({sql}) ");
  93. }
  94. }
  95. }