예제 #1
0
        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);
            }
        }
예제 #2
0
        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);
        }