Сделайте синхронную работу с базой данных асинхронной

#c# #asp.net-mvc #entity-framework-6 #asp.net-4.5

Вопрос:

Я хочу использовать массовые операции с базами данных в Asp.Net Приложение MVC 4.5.2. Есть хорошая библиотека Z.EntityFramework.Extensions , но она стоит 800 долларов. И бесплатная библиотека EF.BulkExtensions , но она не содержит асинхронных методов. Вопрос: если я сделаю этот трюк

 await Task.Run(() => 
{ 
    MyDatabaseContext.BulkUpdate(entities); 
});
 

Будет ли это работать так же, как если бы я использовал асинхронный метод (с точки зрения работы с пулом потоков IIS ) ?

Комментарии:

1.делает ЭФ.Объемные расширения имеют BulkUpdateAsync . Однако bulk update на самом деле нет delete или есть только МАССОВАЯ ВСТАВКА (т. Е. Вставка большого количества данных с минимальным ведением журнала). Все библиотеки, которые говорят о «массовых обновлениях», фактически генерируют команду SQL в фоновом режиме, которая обычно отправляет данные в виде табличного типа или части команды СЛИЯНИЯ.

2. @PanagiotisKanavos нет, у него нет асинхронности. Я использую EF. Объемные расширения.1.4.2 с .netframework 4.5.2. Ваша ссылка указывает на библиотеку EFCore. Я попытаюсь обновить версию фреймворка.

3. EFCore совместим с net framework 4.6 и EF. Ядро 3 . Но у меня есть зависимость от EntityFramework.extenDED, которая зависит от простой структуры сущностей

4. Тогда не используйте этот метод. Там нет команды МАССОВОГО ОБНОВЛЕНИЯ, которая ведет себя так BULK INSERT , как это делает, т. Е. Использует минимальное ведение журнала для вставки данных максимально быстрым способом. То, что делает каждая библиотека, претендующая на «массовое обновление»,-это создание простой старой, полностью зарегистрированной UPDATE команды, которая каким-то образом соединяется с новыми данными либо в виде параметра табличного значения, либо данных в VALUES предложении. Ни один из этих вариантов не может эффективно использовать индексы, что приводит к неоптимальной производительности и просто не масштабируется до большого количества строк

5. Было бы намного быстрее, если бы вы вставили строки в промежуточную таблицу с помощью SqlBulkCopy , а затем выполнили ОБНОВЛЕНИЕ целевого объекта, который присоединился к промежуточной таблице ie UPDATE target SET .... FROM target inner join staging on staging.ID=target.ID .

Ответ №1:

Вы должны, по крайней мере, сделать что-то вроде:

 var task = new Task(() => { MyDatabaseContext.BulkUpdate(entities) }, TaskCreationOptions.LongRunning);
await task;
 

Это гарантирует, что ваша задача выполняется в собственном потоке и не занимает задачу из пула задач.