diff --git a/src/Dapper.Bulk/DapperBulk.cs b/src/Dapper.Bulk/DapperBulk.cs
index 956060c..3c366dc 100644
--- a/src/Dapper.Bulk/DapperBulk.cs
+++ b/src/Dapper.Bulk/DapperBulk.cs
@@ -22,14 +22,15 @@ public static class DapperBulk
/// The type being inserted.
/// Open SqlConnection
/// Entities to insert
+ /// TableName
/// The transaction to run under, null (the default) if none
/// Number of bulk items inserted together, 0 (the default) if all
/// Number of seconds before bulk command execution timeout, 30 (the default)
/// Usage of db generated ids. By default DB generated IDs are used (identityInsert=false)
- public static void BulkInsert(this SqlConnection connection, IEnumerable data, SqlTransaction transaction = null, int batchSize = 0, int bulkCopyTimeout = 30, bool identityInsert = false)
+ public static void BulkInsert(this SqlConnection connection, IEnumerable data, string tableName, SqlTransaction transaction = null, int batchSize = 0, int bulkCopyTimeout = 30, bool identityInsert = false)
{
var type = typeof(T);
- BulkInsert(connection,type,data.Cast(),transaction,batchSize,bulkCopyTimeout,identityInsert);
+ BulkInsert(connection, type, data.Cast(), tableName, transaction, batchSize, bulkCopyTimeout, identityInsert);
}
///
@@ -39,28 +40,34 @@ public static void BulkInsert(this SqlConnection connection, IEnumerable d
/// Open SqlConnection
/// The type being inserted.
/// Entities to insert
+ /// TableName
/// The transaction to run under, null (the default) if none
/// Number of bulk items inserted together, 0 (the default) if all
/// Number of seconds before bulk command execution timeout, 30 (the default)
/// Usage of db generated ids. By default DB generated IDs are used (identityInsert=false)
- public static void BulkInsert(this SqlConnection connection, Type type, IEnumerable data, SqlTransaction transaction = null, int batchSize = 0, int bulkCopyTimeout = 30, bool identityInsert = false)
- {
- var tableName = TableMapper.GetTableName(type);
+ public static void BulkInsert(this SqlConnection connection, Type type, IEnumerable data, string tableName, SqlTransaction transaction = null, int batchSize = 0, int bulkCopyTimeout = 30, bool identityInsert = false)
+ {
+ tableName = string.IsNullOrWhiteSpace(tableName) ? TableMapper.GetTableName(type) : tableName;
var allProperties = PropertiesCache.TypePropertiesCache(type);
var keyProperties = PropertiesCache.KeyPropertiesCache(type);
var computedProperties = PropertiesCache.ComputedPropertiesCache(type);
var columns = PropertiesCache.GetColumnNamesCache(type);
var insertProperties = allProperties.Except(computedProperties).ToList();
-
+
if (!identityInsert)
insertProperties = insertProperties.Except(keyProperties).ToList();
var (identityInsertOn, identityInsertOff, sqlBulkCopyOptions) = GetIdentityInsertOptions(identityInsert, tableName);
-
+
var insertPropertiesString = GetColumnsStringSqlServer(insertProperties, columns);
var tempToBeInserted = $"#TempInsert_{tableName}".Replace(".", string.Empty);
+ if (connection.State != ConnectionState.Open)
+ {
+ connection.Open();
+ }
+
connection.Execute($@"SELECT TOP 0 {insertPropertiesString} INTO {tempToBeInserted} FROM {FormatTableName(tableName)} target WITH(NOLOCK);", null, transaction);
using (var bulkCopy = new SqlBulkCopy(connection, sqlBulkCopyOptions, transaction))
@@ -85,15 +92,16 @@ public static void BulkInsert(this SqlConnection connection, Type type, IEnumera
/// The element type of the array
/// Open SqlConnection
/// Entities to insert
+ /// TableName
/// The transaction to run under, null (the default) if none
/// Number of bulk items inserted together, 0 (the default) if all
/// Number of seconds before bulk command execution timeout, 30 (the default)
/// Usage of db generated ids. By default DB generated IDs are used (identityInsert=false)
/// Inserted entities
- public static IEnumerable BulkInsertAndSelect(this SqlConnection connection, IEnumerable data, SqlTransaction transaction = null, int batchSize = 0, int bulkCopyTimeout = 30, bool identityInsert = false)
+ public static IEnumerable BulkInsertAndSelect(this SqlConnection connection, IEnumerable data, string tableName, SqlTransaction transaction = null, int batchSize = 0, int bulkCopyTimeout = 30, bool identityInsert = false)
{
var type = typeof(T);
- var tableName = TableMapper.GetTableName(type);
+ tableName = string.IsNullOrWhiteSpace(tableName) ? TableMapper.GetTableName(type) : tableName;
var allProperties = PropertiesCache.TypePropertiesCache(type);
var keyProperties = PropertiesCache.KeyPropertiesCache(type);
var computedProperties = PropertiesCache.ComputedPropertiesCache(type);
@@ -102,18 +110,18 @@ public static IEnumerable BulkInsertAndSelect(this SqlConnection connectio
if (keyProperties.Count == 0)
{
var dataList = data.ToList();
- connection.BulkInsert(dataList, transaction, batchSize, bulkCopyTimeout);
+ connection.BulkInsert(dataList, tableName, transaction, batchSize, bulkCopyTimeout);
return dataList;
}
var insertProperties = allProperties.Except(computedProperties).ToList();
-
+
if (!identityInsert)
insertProperties = insertProperties.Except(keyProperties).ToList();
var (identityInsertOn, identityInsertOff, sqlBulkCopyOptions) = GetIdentityInsertOptions(identityInsert, tableName);
-
- var keyPropertiesString = GetColumnsStringSqlServer(keyProperties,columns);
+
+ var keyPropertiesString = GetColumnsStringSqlServer(keyProperties, columns);
var keyPropertiesInsertedString = GetColumnsStringSqlServer(keyProperties, columns, "inserted.");
var insertPropertiesString = GetColumnsStringSqlServer(insertProperties, columns);
var allPropertiesString = GetColumnsStringSqlServer(allProperties, columns, "target.");
@@ -121,6 +129,11 @@ public static IEnumerable BulkInsertAndSelect(this SqlConnection connectio
var tempToBeInserted = $"#TempInsert_{tableName}".Replace(".", string.Empty);
var tempInsertedWithIdentity = $"@TempInserted_{tableName}".Replace(".", string.Empty);
+ if (connection.State != ConnectionState.Open)
+ {
+ connection.Open();
+ }
+
connection.Execute($"SELECT TOP 0 {insertPropertiesString} INTO {tempToBeInserted} FROM {FormatTableName(tableName)} target WITH(NOLOCK);", null, transaction);
using (var bulkCopy = new SqlBulkCopy(connection, sqlBulkCopyOptions, transaction))
@@ -133,7 +146,7 @@ public static IEnumerable BulkInsertAndSelect(this SqlConnection connectio
var table = string.Join(", ", keyProperties.Select(k => $"[{(columns.ContainsKey(k.Name) ? columns[k.Name] : k.Name)}] bigint"));
var joinOn = string.Join(" AND ", keyProperties.Select(k => $"target.[{(columns.ContainsKey(k.Name) ? columns[k.Name] : k.Name)}] = ins.[{(columns.ContainsKey(k.Name) ? columns[k.Name] : k.Name)}]"));
-
+
return connection.Query($@"
{identityInsertOn}
DECLARE {tempInsertedWithIdentity} TABLE ({table})
@@ -154,29 +167,35 @@ public static IEnumerable BulkInsertAndSelect(this SqlConnection connectio
/// The type being inserted.
/// Open SqlConnection
/// Entities to insert
+ /// TableName
/// The transaction to run under, null (the default) if none
/// Number of bulk items inserted together, 0 (the default) if all
/// Number of seconds before bulk command execution timeout, 30 (the default)
/// Usage of db generated ids. By default DB generated IDs are used (identityInsert=false)
- public static async Task BulkInsertAsync(this SqlConnection connection, IEnumerable data, SqlTransaction transaction = null, int batchSize = 0, int bulkCopyTimeout = 30, bool identityInsert = false)
+ public static async Task BulkInsertAsync(this SqlConnection connection, IEnumerable data, string tableName, SqlTransaction transaction = null, int batchSize = 0, int bulkCopyTimeout = 30, bool identityInsert = false)
{
var type = typeof(T);
- var tableName = TableMapper.GetTableName(type);
+ tableName = string.IsNullOrWhiteSpace(tableName) ? TableMapper.GetTableName(type) : tableName;
var allProperties = PropertiesCache.TypePropertiesCache(type);
var keyProperties = PropertiesCache.KeyPropertiesCache(type);
var computedProperties = PropertiesCache.ComputedPropertiesCache(type);
var columns = PropertiesCache.GetColumnNamesCache(type);
var insertProperties = allProperties.Except(computedProperties).ToList();
-
+
if (!identityInsert)
insertProperties = insertProperties.Except(keyProperties).ToList();
var (identityInsertOn, identityInsertOff, sqlBulkCopyOptions) = GetIdentityInsertOptions(identityInsert, tableName);
-
- var insertPropertiesString = GetColumnsStringSqlServer(insertProperties,columns);
+
+ var insertPropertiesString = GetColumnsStringSqlServer(insertProperties, columns);
var tempToBeInserted = $"#TempInsert_{tableName}".Replace(".", string.Empty);
+ if (connection.State != ConnectionState.Open)
+ {
+ connection.Open();
+ }
+
await connection.ExecuteAsync($@"SELECT TOP 0 {insertPropertiesString} INTO {tempToBeInserted} FROM {FormatTableName(tableName)} target WITH(NOLOCK);", null, transaction);
using (var bulkCopy = new SqlBulkCopy(connection, sqlBulkCopyOptions, transaction))
@@ -202,15 +221,16 @@ await connection.ExecuteAsync($@"
/// The type being inserted.
/// Open SqlConnection
/// Entities to insert
+ /// TableName
/// The transaction to run under, null (the default) if none
/// Number of bulk items inserted together, 0 (the default) if all
/// Number of seconds before bulk command execution timeout, 30 (the default)
/// Usage of db generated ids. By default DB generated IDs are used (identityInsert=false)
/// Inserted entities
- public static async Task> BulkInsertAndSelectAsync(this SqlConnection connection, IEnumerable data, SqlTransaction transaction = null, int batchSize = 0, int bulkCopyTimeout = 30, bool identityInsert = false)
+ public static async Task> BulkInsertAndSelectAsync(this SqlConnection connection, IEnumerable data, string tableName, SqlTransaction transaction = null, int batchSize = 0, int bulkCopyTimeout = 30, bool identityInsert = false)
{
var type = typeof(T);
- var tableName = TableMapper.GetTableName(type);
+ tableName = string.IsNullOrWhiteSpace(tableName) ? TableMapper.GetTableName(type) : tableName;
var allProperties = PropertiesCache.TypePropertiesCache(type);
var keyProperties = PropertiesCache.KeyPropertiesCache(type);
var computedProperties = PropertiesCache.ComputedPropertiesCache(type);
@@ -219,28 +239,33 @@ public static async Task> BulkInsertAndSelectAsync(this SqlCon
if (keyProperties.Count == 0)
{
var dataList = data.ToList();
- await connection.BulkInsertAsync(dataList, transaction, batchSize, bulkCopyTimeout);
+ await connection.BulkInsertAsync(dataList, tableName, transaction, batchSize, bulkCopyTimeout);
return dataList;
}
var insertProperties = allProperties.Except(computedProperties).ToList();
-
+
if (!identityInsert)
insertProperties = insertProperties.Except(keyProperties).ToList();
var (identityInsertOn, identityInsertOff, sqlBulkCopyOptions) = GetIdentityInsertOptions(identityInsert, tableName);
-
- var keyPropertiesString = GetColumnsStringSqlServer(keyProperties,columns);
- var keyPropertiesInsertedString = GetColumnsStringSqlServer(keyProperties,columns, "inserted.");
- var insertPropertiesString = GetColumnsStringSqlServer(insertProperties,columns);
+
+ var keyPropertiesString = GetColumnsStringSqlServer(keyProperties, columns);
+ var keyPropertiesInsertedString = GetColumnsStringSqlServer(keyProperties, columns, "inserted.");
+ var insertPropertiesString = GetColumnsStringSqlServer(insertProperties, columns);
var allPropertiesString = GetColumnsStringSqlServer(allProperties, columns, "target.");
var tempToBeInserted = $"#TempInsert_{tableName}".Replace(".", string.Empty);
var tempInsertedWithIdentity = $"@TempInserted_{tableName}".Replace(".", string.Empty);
+ if (connection.State != ConnectionState.Open)
+ {
+ connection.Open();
+ }
+
await connection.ExecuteAsync($@"SELECT TOP 0 {insertPropertiesString} INTO {tempToBeInserted} FROM {FormatTableName(tableName)} target WITH(NOLOCK);", null, transaction);
- using (var bulkCopy = new SqlBulkCopy(connection,sqlBulkCopyOptions, transaction))
+ using (var bulkCopy = new SqlBulkCopy(connection, sqlBulkCopyOptions, transaction))
{
bulkCopy.BulkCopyTimeout = bulkCopyTimeout;
bulkCopy.BatchSize = batchSize;
@@ -272,7 +297,7 @@ private static string GetColumnsStringSqlServer(IEnumerable proper
return string.Join(", ", properties.Select(property => $"{tablePrefix}[{columnNames[property.Name]}] "));
}
-
+
private static DataTable ToDataTable(IEnumerable data, IList properties)
{
var typeCasts = new Type[properties.Count];
@@ -339,9 +364,9 @@ internal static string FormatTableName(string table)
}
private static (string identityInsertOn, string identityInsertOff, SqlBulkCopyOptions bulkCopyOptions)
- GetIdentityInsertOptions(bool identityInsert, string tableName)
- => identityInsert
- ? ($"SET IDENTITY_INSERT {FormatTableName(tableName)} ON",
- $"SET IDENTITY_INSERT {FormatTableName(tableName)} OFF", SqlBulkCopyOptions.KeepIdentity)
- : (string.Empty, string.Empty, SqlBulkCopyOptions.Default);
+ GetIdentityInsertOptions(bool identityInsert, string tableName)=> (string.Empty, string.Empty, SqlBulkCopyOptions.Default);
+ //=> identityInsert
+ // ? ($"SET IDENTITY_INSERT {FormatTableName(tableName)} ON",
+ // $"SET IDENTITY_INSERT {FormatTableName(tableName)} OFF", SqlBulkCopyOptions.KeepIdentity)
+ // : (string.Empty, string.Empty, SqlBulkCopyOptions.Default);
}