From 6eb720d2aeb29a64dcccee1b36856b36698013a2 Mon Sep 17 00:00:00 2001
From: 28810 <28810@YEXIANGQIN>
Date: Thu, 9 Jan 2020 15:27:46 +0800
Subject: [PATCH] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSql.Provider.MySql?=
=?UTF-8?q?Connector=20=E6=89=A9=E5=B1=95=E6=96=B9=E6=B3=95=20ExecuteMySql?=
=?UTF-8?q?BulkCopy=EF=BC=9B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../FreeSql.Provider.MySqlConnector.csproj | 2 +-
.../FreeSqlMySqlConnectorGlobalExtensions.cs | 147 ++++++++++++++++++
2 files changed, 148 insertions(+), 1 deletion(-)
create mode 100644 Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs
diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj
index 93d50569..b40a0440 100644
--- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj
+++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj
@@ -23,7 +23,7 @@
-
+
diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs b/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs
new file mode 100644
index 00000000..6b22af02
--- /dev/null
+++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs
@@ -0,0 +1,147 @@
+using FreeSql;
+using MySql.Data.MySqlClient;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+
+public static class FreeSqlMySqlConnectorGlobalExtensions
+{
+ #region ExecuteMySqlBulkCopy
+ ///
+ /// MySql MySqlCopyBulk 批量插入功能
+ /// 使用 IgnoreColumns/InsertColumns 设置忽略/指定导入的列
+ /// 使用 WithConnection/WithTransaction 传入连接/事务对象
+ /// 提示:若本方法不能满足,请使用 IInsert<T>.ToDataTable 方法得到 DataTable 对象后,自行处理。
+ /// MySqlCopyBulk 与 insert into t values(..),(..),(..) 性能测试参考:
+ /// 插入180000行,52列:28,405ms 与 38,481ms,10列:6,504ms 与 11,171ms
+ /// 插入10000行,52列:1,142ms 与 2,234ms,10列:339ms 与 866ms
+ /// 插入5000行,52列:657ms 与 1,136ms,10列:257ms 与 366ms
+ /// 插入2000行,52列:451ms 与 284ms,10列:116ms 与 80ms
+ /// 插入1000行,52列:435ms 与 239ms,10列:87ms 与 83ms
+ /// 插入500行,52列:592ms 与 167ms,10列:100ms 与 50ms
+ /// 插入100行,52列:47ms 与 66ms,10列:16ms 与 24ms
+ /// 插入50行,52列:22ms 与 30ms,10列:16ms 与 34ms
+ ///
+ ///
+ ///
+ ///
+ public static void ExecuteMySqlBulkCopy(this IInsert that, int? bulkCopyTimeout = null) where T : class
+ {
+ var insert = that as FreeSql.MySql.Curd.MySqlInsert;
+ if (insert == null) throw new Exception("ExecuteMySqlBulkCopy 是 FreeSql.Provider.MySqlConnector 特有的功能");
+
+ var dt = that.ToDataTable();
+ if (dt.Rows.Count == 0) return;
+
+ Action writeToServer = bulkCopy =>
+ {
+ if (bulkCopyTimeout.HasValue) bulkCopy.BulkCopyTimeout = bulkCopyTimeout.Value;
+ bulkCopy.DestinationTableName = dt.TableName;
+ bulkCopy.WriteToServer(dt);
+ };
+
+ try
+ {
+ if (insert.InternalConnection == null && insert.InternalTransaction == null)
+ {
+ using (var conn = insert.InternalOrm.Ado.MasterPool.Get())
+ {
+ writeToServer(new MySqlBulkCopy(conn.Value as MySqlConnection));
+ }
+ }
+ else if (insert.InternalTransaction != null)
+ {
+ writeToServer(new MySqlBulkCopy(insert.InternalTransaction.Connection as MySqlConnection));
+ }
+ else if (insert.InternalConnection != null)
+ {
+ var conn = insert.InternalConnection as MySqlConnection;
+ var isNotOpen = false;
+ if (conn.State != System.Data.ConnectionState.Open)
+ {
+ isNotOpen = true;
+ conn.Open();
+ }
+ try
+ {
+ writeToServer(new MySqlBulkCopy(conn));
+ }
+ finally
+ {
+ if (isNotOpen)
+ conn.Close();
+ }
+ }
+ else
+ {
+ throw new NotImplementedException("ExecuteMySqlBulkCopy 未实现错误,请反馈给作者");
+ }
+ }
+ finally
+ {
+ dt.Clear();
+ }
+ }
+#if net40
+#else
+ async public static Task ExecuteMySqlBulkCopyAsync(this IInsert that, int? bulkCopyTimeout = null) where T : class
+ {
+ var insert = that as FreeSql.MySql.Curd.MySqlInsert;
+ if (insert == null) throw new Exception("ExecuteMySqlBulkCopyAsync 是 FreeSql.Provider.MySqlConnector 特有的功能");
+
+ var dt = that.ToDataTable();
+ if (dt.Rows.Count == 0) return;
+
+ Func writeToServer = bulkCopy =>
+ {
+ if (bulkCopyTimeout.HasValue) bulkCopy.BulkCopyTimeout = bulkCopyTimeout.Value;
+ bulkCopy.DestinationTableName = dt.TableName;
+ return bulkCopy.WriteToServerAsync(dt);
+ };
+
+ try
+ {
+ if (insert.InternalConnection == null && insert.InternalTransaction == null)
+ {
+ using (var conn = insert.InternalOrm.Ado.MasterPool.Get())
+ {
+ await writeToServer(new MySqlBulkCopy(conn.Value as MySqlConnection));
+ }
+ }
+ else if (insert.InternalTransaction != null)
+ {
+ await writeToServer(new MySqlBulkCopy(insert.InternalTransaction.Connection as MySqlConnection));
+ }
+ else if (insert.InternalConnection != null)
+ {
+ var conn = insert.InternalConnection as MySqlConnection;
+ var isNotOpen = false;
+ if (conn.State != System.Data.ConnectionState.Open)
+ {
+ isNotOpen = true;
+ conn.Open();
+ }
+ try
+ {
+ await writeToServer(new MySqlBulkCopy(conn));
+ }
+ finally
+ {
+ if (isNotOpen)
+ conn.Close();
+ }
+ }
+ else
+ {
+ throw new NotImplementedException("ExecuteMySqlBulkCopyAsync 未实现错误,请反馈给作者");
+ }
+ }
+ finally
+ {
+ dt.Clear();
+ }
+ }
+#endif
+ #endregion
+}