使同步数据库操作异步
Posted
技术标签:
【中文标题】使同步数据库操作异步【英文标题】:Make Synchronous database operation asynchronous 【发布时间】:2021-11-28 07:37:32 【问题描述】:我想在 Asp.Net MVC 4.5.2 应用程序中使用批量数据库操作。
有很好的库Z.EntityFramework.Extensions
,但要 800 美元。
还有免费的 lib EF.BulkExtensions
,但它不包含异步方法。
问题:如果我会这样做
await Task.Run(() =>
MyDatabaseContext.BulkUpdate(entities);
);
它会像我使用异步方法一样工作吗(就使用 IIS 的线程池而言)?
【问题讨论】:
EF.BulkExtensions 确实有一个BulkUpdateAsync
。但实际上没有bulk update
或delete
,只有BULK INSERT(即以最少的日志记录插入大量数据)。所有谈论“批量更新”的库实际上都会在后台生成一个 SQL 命令,该命令通常将数据作为表值类型或 MERGE 命令的一部分发送。
@PanagiotisKanavos 不,它没有异步功能。我将 EF.BulkExtensions.1.4.2 与 .netframework 4.5.2 一起使用。您的链接指向 EFCore 库。我会尝试升级框架版本。
EFCore 与网络框架 4.6+ 和 EF.Core 3+ 兼容。但是我依赖于EntityFramework.extenDED,它依赖于简单的实体框架
那就不要使用那个方法了。没有像BULK INSERT
那样运行的 BULK UPDATE 命令,即使用最少的日志记录以尽可能最快的方式插入数据。每个声称“批量更新”的库所做的是生成一个普通旧的、完全记录的UPDATE
命令,该命令以某种方式与新数据结合,无论是表值参数的形式还是VALUES
中的数据条款。这些选项都不能很好地利用索引,从而导致性能欠佳,并且不能扩展到大量行
如果您使用SqlBulkCopy
将行插入到临时表中,然后对与临时表连接的目标(即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;
这可确保您的任务在其自己的线程中运行,并且不会占用任务池中的任务。
【讨论】:
以上是关于使同步数据库操作异步的主要内容,如果未能解决你的问题,请参考以下文章