diff --git a/src/Dapper.Contrib.BulkInsert/Dapper.Contrib.BulkInsert.csproj b/src/Dapper.Contrib.BulkInsert/Dapper.Contrib.BulkInsert.csproj
index 2b646ea..8d33190 100644
--- a/src/Dapper.Contrib.BulkInsert/Dapper.Contrib.BulkInsert.csproj
+++ b/src/Dapper.Contrib.BulkInsert/Dapper.Contrib.BulkInsert.csproj
@@ -8,7 +8,7 @@
https://github.com/YahuiWong/Dapper.Contrib.BulkInsert.git
git
clickhouse,dapper,bulk,mysql,sqlserver
- 0.1.5
+ 0.1.7
true
https://github.com/YahuiWong/Dapper.Contrib.BulkInsert/blob/master/LICENSE
Dapper.Contrib.BulkInsert
diff --git a/src/Dapper.Contrib.BulkInsert/SqlMapperExtensions.Async.cs b/src/Dapper.Contrib.BulkInsert/SqlMapperExtensions.Async.cs
index 31ff3b5..69e5f18 100644
--- a/src/Dapper.Contrib.BulkInsert/SqlMapperExtensions.Async.cs
+++ b/src/Dapper.Contrib.BulkInsert/SqlMapperExtensions.Async.cs
@@ -27,7 +27,7 @@ public static async Task InsertBulkAsync(this IDbConnection connection, IEnum
var wasClosed = connection.State == ConnectionState.Closed;
if (wasClosed) connection.Open();
- await connection.ExecuteAsync(cmd.Item1,cmd.Item2, null, commandTimeout);
+ await connection.ExecuteAsync(cmd.Item1,cmd.Item2, null, commandTimeout, CommandType.Text);
if (wasClosed) connection.Close();
}
///
@@ -127,8 +127,19 @@ public static async Task InsertBulkAsync(this ClickHouse.Client.ADO.ClickHous
if (wasClosed) connection.Close();
+ }
+ ///
+ /// Inserts an entity into table "Ts" and returns identity id or number of inserted rows if inserting a list.
+ ///
+ /// Open SqlConnection
+ /// Entity to insert, can be list of entities
+ /// Identity of inserted entity, or number of inserted rows if inserting a list
+ public static async Task InsertBulkAsync(this ClickHouse.Ado.ClickHouseConnection connection, IEnumerable entityToInsert, int? commandTimeout = null)
+ {
+ await Task.Run(() => InsertBulk(connection, entityToInsert, commandTimeout)
+ );
+
}
-
}
diff --git a/src/Dapper.Contrib.BulkInsert/SqlMapperExtensions.cs b/src/Dapper.Contrib.BulkInsert/SqlMapperExtensions.cs
index bd1f2e8..5e99067 100644
--- a/src/Dapper.Contrib.BulkInsert/SqlMapperExtensions.cs
+++ b/src/Dapper.Contrib.BulkInsert/SqlMapperExtensions.cs
@@ -323,6 +323,18 @@ private static (string, DynamicParameters) GenerateBulkSql(IDbConnection conn
return (cmd,parameters);
}
+
+ ///
+ /// Inserts an entity into table "Ts" and returns identity id or number of inserted rows if inserting a list.
+ ///
+ /// Open SqlConnection
+ /// Entity to insert, can be list of entities
+ /// Identity of inserted entity, or number of inserted rows if inserting a list
+ public static void InsertBulk(this ClickHouse.Client.ADO.ClickHouseConnection connection, IEnumerable entityToInsert, int? commandTimeout = null)
+ {
+ InsertBulkAsync(connection, entityToInsert, commandTimeout).GetAwaiter().GetResult();
+ }
+
///
/// Inserts an entity into table "Ts" and returns identity id or number of inserted rows if inserting a list.
///
@@ -339,17 +351,133 @@ public static void InsertBulk(this IDbConnection connection, IEnumerable e
connection.Execute(cmd.Item1, cmd.Item2, null, commandTimeout);
if (wasClosed) connection.Close();
}
+ private static (string, List) GenerateCHBulkSql(IDbConnection connection, IEnumerable entityToInsert)
+ {
+ var type = entityToInsert.GetType();
+ var typeInfo = type.GetTypeInfo();
+ bool implementsGenericIEnumerableOrIsGenericIEnumerable =
+ typeInfo.ImplementedInterfaces.Any(ti =>
+ ti.IsGenericType() && ti.GetGenericTypeDefinition() == typeof(IEnumerable<>)) ||
+ typeInfo.GetGenericTypeDefinition() == typeof(IEnumerable<>);
+
+ if (implementsGenericIEnumerableOrIsGenericIEnumerable)
+ {
+ type = type.GetGenericArguments()[0];
+ }
+
+ var name = GetTableName(type);
+ var sbColumnList = new StringBuilder(null);
+ var allProperties = TypePropertiesCache(type);
+ var keyProperties = KeyPropertiesCache(type);
+ var computedProperties = ComputedPropertiesCache(type);
+ var allPropertiesExceptKeyAndComputed =
+ allProperties.Except(keyProperties.Union(computedProperties)).ToList();
+
+ for (var i = 0; i < allPropertiesExceptKeyAndComputed.Count; i++)
+ {
+ var property = allPropertiesExceptKeyAndComputed[i];
+ sbColumnList.AppendFormat("{0}", GetColumnName(property));
+ if (i < allPropertiesExceptKeyAndComputed.Count - 1)
+ sbColumnList.Append(", ");
+ }
+
+ //var sbParameterList = new StringBuilder(null);
+ List dynamics = new List();
+
+ for (int j = 0, length = Enumerable.Count(entityToInsert); j < length; j++)
+ {
+ var item = Enumerable.ElementAt(entityToInsert, j);
+ {
+ List dynamicsParams = new List();
+ //sbParameterList.Append("(");
+ for (int i = 0,count= allPropertiesExceptKeyAndComputed.Count; i < count; i++)
+ {
+
+ var property = allPropertiesExceptKeyAndComputed[i];
+
+ var val = property.GetValue(item);
+ //var columnName = $"@{GetColumnName(property)}{j}{i}";
+ //sbParameterList.Append(columnName);
+ if (property.PropertyType.IsValueType)
+ {
+ if (property.PropertyType == typeof(DateTime))
+ {
+ var datetimevalue = Convert.ToDateTime(val);
+ if (property.GetCustomAttribute() != null)
+ {
+ //parameters.Add(columnName, datetimevalue.Date, DbType.Date);
+ dynamicsParams.Add(datetimevalue.Date);
+ //sbParameterList.AppendFormat("'{0:yyyy-MM-dd}'", val);
+ }
+ else
+ {
+ dynamicsParams.Add(datetimevalue);
+ //parameters.Add(columnName, datetimevalue, DbType.DateTime);
+ //sbParameterList.AppendFormat("'{0:yyyy-MM-dd HH:mm:ss}'", val);
+ }
+ }
+ else if (property.PropertyType == typeof(Boolean))
+ {
+ var boolvalue = Convert.ToBoolean(val);
+
+ {
+ //parameters.Add(columnName, boolvalue ? 1 : 0, DbType.Int32);
+ dynamicsParams.Add(boolvalue);
+ //sbParameterList.AppendFormat("'{0:yyyy-MM-dd HH:mm:ss}'", val);
+ }
+ }
+ else
+ {
+ dynamicsParams.Add(val);
+ //sbParameterList.AppendFormat("{0}", FixValue(val));
+ }
+ }
+ else
+ {
+ dynamicsParams.Add(val);
+ ///sbParameterList.AppendFormat("'{0}'", FixValue(val));
+ }
+
+ //if (i < allPropertiesExceptKeyAndComputed.Count - 1)
+ // sbParameterList.Append(", ");
+
+ }
+ dynamics.Add(dynamicsParams.ToArray());
+ //sbParameterList.Append("),");
+ }
+ }
+
+
+ //sbParameterList.Remove(sbParameterList.Length - 1, 1);
+ //sbParameterList.Append(";");
+ //insert list of entities
+ var cmd = $"insert into {name} ({sbColumnList}) values @bulk; ";
+ return (cmd, dynamics);
+ }
///
/// Inserts an entity into table "Ts" and returns identity id or number of inserted rows if inserting a list.
///
/// Open SqlConnection
/// Entity to insert, can be list of entities
/// Identity of inserted entity, or number of inserted rows if inserting a list
- public static void InsertBulk(this ClickHouse.Client.ADO.ClickHouseConnection connection, IEnumerable entityToInsert, int? commandTimeout = null)
+ public static void InsertBulk(this ClickHouse.Ado.ClickHouseConnection connection, IEnumerable entityToInsert, int? commandTimeout = null)
{
- InsertBulkAsync(connection, entityToInsert, commandTimeout).GetAwaiter().GetResult();
- }
+ var cmd = GenerateCHBulkSql(connection, entityToInsert);
+
+ var wasClosed = connection.State == ConnectionState.Closed;
+ if (wasClosed) connection.Open();
+
+ var command = connection.CreateCommand();
+ command.CommandText = cmd.Item1;
+ command.Parameters.Add(new ClickHouse.Ado.ClickHouseParameter
+ {
+ ParameterName = "bulk",
+ Value = cmd.Item2
+ });
+ command.ExecuteNonQuery();
+ if (wasClosed) connection.Close();
+ }
///
/// Specifies a custom callback that detects the database type instead of relying on the default strategy (the name of the connection type object).