Refactored such that the a IBulkSqlInsertProvider can be used, to diff. between SqlCe and SqlServer

This commit is contained in:
Bjarke Berg
2019-12-12 12:55:17 +01:00
parent f9286d1eda
commit d36ff6d509
29 changed files with 212 additions and 142 deletions

View File

@@ -51,56 +51,6 @@ namespace Umbraco.Core.Persistence
}
}
/// <summary>
/// Bulk-inserts records.
/// </summary>
/// <typeparam name="T">The type of the records.</typeparam>
/// <param name="database">The database.</param>
/// <param name="records">The records.</param>
/// <param name="useNativeBulkInsert">Whether to use native bulk insert when available.</param>
/// <returns>The number of records that were inserted.</returns>
public static int BulkInsertRecords<T>(this IUmbracoDatabase database, IEnumerable<T> records, bool useNativeBulkInsert = true)
{
var recordsA = records.ToArray();
if (recordsA.Length == 0) return 0;
var pocoData = database.PocoDataFactory.ForType(typeof(T));
if (pocoData == null) throw new InvalidOperationException("Could not find PocoData for " + typeof(T));
// if (database.DatabaseType.IsSqlCe())
// {
// if (useNativeBulkInsert) return BulkInsertRecordsSqlCe(database, pocoData, recordsA);
// // else, no other choice
// foreach (var record in recordsA)
// database.Insert(record);
// return recordsA.Length;
// }
//TODO FIX Sql CE
if (database.DatabaseType.IsSqlServer())
{
return useNativeBulkInsert && database.DatabaseType.IsSqlServer2008OrLater()
? BulkInsertRecordsSqlServer(database, pocoData, recordsA)
: BulkInsertRecordsWithCommands(database, recordsA);
}
throw new NotSupportedException();
}
/// <summary>
/// Bulk-insert records using commands.
/// </summary>
/// <typeparam name="T">The type of the records.</typeparam>
/// <param name="database">The database.</param>
/// <param name="records">The records.</param>
/// <returns>The number of records that were inserted.</returns>
private static int BulkInsertRecordsWithCommands<T>(IUmbracoDatabase database, T[] records)
{
foreach (var command in database.GenerateBulkInsertCommands(records))
command.ExecuteNonQuery();
return records.Length; // what else?
}
/// <summary>
/// Creates bulk-insert commands.
/// </summary>
@@ -174,43 +124,6 @@ namespace Umbraco.Core.Persistence
}
/// <summary>
/// Bulk-insert records using SqlServer BulkCopy method.
/// </summary>
/// <typeparam name="T">The type of the records.</typeparam>
/// <param name="database">The database.</param>
/// <param name="pocoData">The PocoData object corresponding to the record's type.</param>
/// <param name="records">The records.</param>
/// <returns>The number of records that were inserted.</returns>
internal static int BulkInsertRecordsSqlServer<T>(IUmbracoDatabase database, PocoData pocoData, IEnumerable<T> records)
{
// create command against the original database.Connection
using (var command = database.CreateCommand(database.Connection, CommandType.Text, string.Empty))
{
// use typed connection and transactionf or SqlBulkCopy
var tConnection = GetTypedConnection<SqlConnection>(database.Connection);
var tTransaction = GetTypedTransaction<SqlTransaction>(command.Transaction);
var tableName = pocoData.TableInfo.TableName;
var syntax = database.SqlContext.SqlSyntax as SqlServerSyntaxProvider;
if (syntax == null) throw new NotSupportedException("SqlSyntax must be SqlServerSyntaxProvider.");
using (var copy = new SqlBulkCopy(tConnection, SqlBulkCopyOptions.Default, tTransaction) { BulkCopyTimeout = 10000, DestinationTableName = tableName })
using (var bulkReader = new PocoDataDataReader<T, SqlServerSyntaxProvider>(records, pocoData, syntax))
{
//we need to add column mappings here because otherwise columns will be matched by their order and if the order of them are different in the DB compared
//to the order in which they are declared in the model then this will not work, so instead we will add column mappings by name so that this explicitly uses
//the names instead of their ordering.
foreach (var col in bulkReader.ColumnMappings)
{
copy.ColumnMappings.Add(col.DestinationColumn, col.DestinationColumn);
}
copy.WriteToServer(bulkReader);
return bulkReader.RecordsAffected;
}
}
}
}
}