private async Task BulkInsertAsync <T>( IEntityType entityType, IEnumerable <T> entities, string?schema, string tableName, IBulkInsertOptions options, CancellationToken cancellationToken = default) where T : class { if (entities == null) { throw new ArgumentNullException(nameof(entities)); } if (tableName == null) { throw new ArgumentNullException(nameof(tableName)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } if (!(options is SqlServerBulkInsertOptions sqlServerOptions)) { sqlServerOptions = new SqlServerBulkInsertOptions(options); } var factory = _ctx.GetService <IEntityDataReaderFactory>(); var properties = options.MembersToInsert.GetPropertiesForInsert(entityType); var sqlCon = (SqlConnection)_ctx.Database.GetDbConnection(); var sqlTx = (SqlTransaction?)_ctx.Database.CurrentTransaction?.GetDbTransaction(); using var reader = factory.Create(_ctx, entities, properties); using var bulkCopy = CreateSqlBulkCopy(sqlCon, sqlTx, schema, tableName, sqlServerOptions); var columns = SetColumnMappings(bulkCopy, reader); await _ctx.Database.OpenConnectionAsync(cancellationToken).ConfigureAwait(false); try { LogInserting(sqlServerOptions.SqlBulkCopyOptions, bulkCopy, columns); var stopwatch = Stopwatch.StartNew(); await bulkCopy.WriteToServerAsync(reader, cancellationToken).ConfigureAwait(false); LogInserted(sqlServerOptions.SqlBulkCopyOptions, stopwatch.Elapsed, bulkCopy, columns); } finally { await _ctx.Database.CloseConnectionAsync().ConfigureAwait(false); } }
private SqlBulkCopy CreateSqlBulkCopy(SqlConnection sqlCon, SqlTransaction?sqlTx, string?schema, string tableName, SqlServerBulkInsertOptions sqlServerOptions) { var bulkCopy = new SqlBulkCopy(sqlCon, sqlServerOptions.SqlBulkCopyOptions, sqlTx) { DestinationTableName = _sqlGenerationHelper.DelimitIdentifier(tableName, schema), EnableStreaming = sqlServerOptions.EnableStreaming }; if (sqlServerOptions.BulkCopyTimeout.HasValue) { bulkCopy.BulkCopyTimeout = (int)sqlServerOptions.BulkCopyTimeout.Value.TotalSeconds; } if (sqlServerOptions.BatchSize.HasValue) { bulkCopy.BatchSize = sqlServerOptions.BatchSize.Value; } return(bulkCopy); }