Upsert огромный объем данных с помощью EFCore.BulkExtensionsC#

Место общения программистов C#
Ответить
Anonymous
 Upsert огромный объем данных с помощью EFCore.BulkExtensions

Сообщение Anonymous »

Я использую приведенную ниже функцию расширения для загрузки данных в EF Core с помощью EFCore.BulkExtensions, но проблема в том, что выполнение этой функции, когда я пытался вставить 2 миллиона записей, занимает около 17 минут, и в последнее время выдается это исключение
Не удалось выделить место для временного хранилища запуска объекта «dbo.SORT: 140737501921280» в базе данных «tempdb», поскольку файловая группа «PRIMARY» заполнена. Освободите дисковое пространство, удалив ненужные файлы, удалив объекты в файловой группе, добавив в файловую группу дополнительные файлы или включив автоматическое увеличение для существующих файлов в файловой группе.\r\nЖурнал транзакций для базы данных tempdb заполнен из-за "ACTIVE_TRANSACTION" и задержанный lsn равен (41:136:347),
и я вижу, что объем памяти для раздела «C» уменьшается, когда я выполнил эту функцию.
Изображение

когда я перезапускаю сервер sql, свободное место становится около 30 ГБ ,
Я пытался использовать многопоточность (параллельную) со вставкой без заметного изменения времени, так что вы порекомендуете или есть ли какие-либо проблемы с переносом кода,
< strong>Примечание: цикл for не занимает слишком много времени, даже если он содержит 2 миллиона записей.
public static async Task AddOrUpdateBulkByTransactionAsync(this DbContext _myDatabaseContext, List data) where TEntity : class
{
using (var transaction = await _myDatabaseContext.Database.BeginTransactionAsync())
{
try
{
_myDatabaseContext.Database.SetCommandTimeout(0);

var currentTime = DateTime.Now;

// Disable change tracking
_myDatabaseContext.ChangeTracker.AutoDetectChangesEnabled = false;

// Set CreatedDate and UpdatedDate for each entity
foreach (var entity in data)
{
var createdDateProperty = entity.GetType().GetProperty("CreatedDate");
if (createdDateProperty != null && (createdDateProperty.GetValue(entity) == null || createdDateProperty.GetValue(entity).Equals(DateTime.MinValue)))
{
// Set CreatedDate only if it's not already set
createdDateProperty.SetValue(entity, currentTime);
}

var updatedDateProperty = entity.GetType().GetProperty("UpdatedDate");
if (updatedDateProperty != null)
{
updatedDateProperty.SetValue(entity, currentTime);
}
}
// Bulk insert or update
var updateByProperties = GetUpdateByProperties();
var bulkConfig = new BulkConfig()
{
UpdateByProperties = updateByProperties,
CalculateStats = true,
SetOutputIdentity = false

};
// Batch size for processing
int batchSize = 50000;
for (int i = 0; i < data.Count; i += batchSize)
{
var batch = data.Skip(i).Take(batchSize).ToList();
await _myDatabaseContext.BulkInsertOrUpdateAsync(batch, bulkConfig);
}

// Commit the transaction if everything succeeds
await transaction.CommitAsync();

return new OperationResultDto
{
OperationResult = bulkConfig.StatsInfo
};
}
catch (Exception ex)
{
// Handle exceptions and roll back the transaction if something goes wrong
transaction.Rollback();
return new OperationResultDto
{
Error = new ErrorDto
{
Details = ex.Message + ex.InnerException?.Message
}
};
}
finally
{
// Re-enable change tracking
_myDatabaseContext.ChangeTracker.AutoDetectChangesEnabled = true;
}
}
}


Подробнее здесь: https://stackoverflow.com/questions/782 ... extensions
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»