public static Task BulkInsertAsync <T>(this SqlConnection connection, IEnumerable <T> entitiesToInsert, SqlTransaction transaction = null, int?commandTimeout = null, CancellationToken cancellationToken = default) where T : class { var engine = new BulkCRUDCommandEngine(); var command = new BulkCommandDefinition <T>( connection, entitiesToInsert, transaction, commandTimeout, cancellationToken ); return(engine.BulkInsertAsync(command)); }
public async Task BulkInsertAsync <T>(BulkCommandDefinition <T> commandDefinition) where T : class { var type = CheckCommandConditions(commandDefinition.Entities, "insert"); var entityTypeResult = MetaData.Models.EntityCache.GetEntity(type) ?? MetaData.TypeAnalyzer.AnalyzeType(type); if (!entityTypeResult.HasPrimaryKey()) { throw new ArgumentException("At least one key column property must be defined."); } if (commandDefinition.Connection.State == ConnectionState.Closed) { await commandDefinition.Connection.OpenAsync(commandDefinition.CancellationToken).ConfigureAwait(false); } var tableName = entityTypeResult.TableName; if (!commandDefinition.TableName.IsNullOrEmpty()) { tableName = commandDefinition.TableName; } var sqlBulkCopy = commandDefinition.Transaction == default ? new SqlBulkCopy(commandDefinition.Connection) { DestinationTableName = tableName } : new SqlBulkCopy(commandDefinition.Connection, SqlBulkCopyOptions.Default, commandDefinition.Transaction) { DestinationTableName = tableName }; if (commandDefinition.CommandTimeout.HasValue) { sqlBulkCopy.BulkCopyTimeout = commandDefinition.CommandTimeout.Value; } var properties = GetProperties(new PropertyRequest { Type = type, Entity = commandDefinition.Entities.First() }); var dataTable = CreateDataTable(properties, sqlBulkCopy); foreach (var entity in commandDefinition.Entities) { // Must be executed for all entities, because OwnsOne Properties can be filled or not filled properties = GetProperties(new PropertyRequest { Type = type, Entity = entity }); var row = dataTable.NewRow(); foreach (var property in properties) { var columnName = property.Prefix.IsNullOrEmpty() ? property.ColumnName : property.Prefix + property.ColumnName ; if (property.TypeHandler == default) { row[columnName] = property.PropertyInfo.GetValue(property.Entity) ?? DBNull.Value; continue; } var cellValue = property.PropertyInfo.GetValue(property.Entity); if (cellValue == null) { row[columnName] = DBNull.Value; } else { var sqlParameter = new SqlParameter(); property.TypeHandler.SetValue(sqlParameter, cellValue); row[columnName] = sqlParameter.Value; } } dataTable.Rows.Add(row); } await sqlBulkCopy.WriteToServerAsync(dataTable, commandDefinition.CancellationToken); }