首页 > 解决方案 > 实体框架核心性能优化以摄取同一张表的非常大的文件夹

问题描述

我有一个后台服务,它在 C# 中将 3600 个 xml 文件(总共 5Gb 文件大小)摄取到 SQL Server 数据库。完成摄取的持续时间约为 16 小时。我使用 hangfire 创建 3 个作业/线程,每个作业将有一个文件夹来摄取,文件夹 A、B、C。

问题是文件夹 C 非常重。我的想法是将文件夹 C 中的文件拆分为两个文件夹,文件夹 C1 和文件夹 C2。所以现在,我有 4 个作业/线程,文件夹 A、B、C1 和 C2。但问题是 C1 和 C2 作业命中数据库错误,我相信这是因为它们都评估同一张表。

保存上下文类型“xxxContext”的更改时,数据库中发生异常。System.InvalidOperationException:在前一个操作完成之前在此上下文上启动了第二个操作。这通常是由使用相同 DbContext 实例的不同线程引起的

还有一次出现此错误:

保存上下文类型“xxxContext”的更改时,数据库中发生异常。System.InvalidOperationException:集合已修改;枚举操作可能无法执行。

来自hangfire的错误如下:

Hangfire.Storage.DistributedLockTimeoutException 超时已过期。在“HangFire:IIngestService.IngestPersonXML”资源上获得分布式锁之前超时已过。

Hangfire.Storage.DistributedLockTimeoutException:超时已过期。在“HangFire:IIngestService.IngestPersonXML”资源上获得分布式锁之前超时已过。

当我使用Parallel.ForEach时,我也收到此错误:

System.InvalidOperationException: '更改非并发集合的操作必须具有独占访问权限。对此集合执行了并发更新并损坏了它的状态。集合的状态不再正确。

我只需要插入到数据库中。无需更新或删除操作。有什么解决方法吗?

标签: c#xmlentity-framework-coreetlbulkinsert

解决方案


EF 不适用于此类操作。为此使用SqlBulCopy
有库为 EF 无缝提供它,但您也可以编写自己的实现 - 它并不复杂

这部分真的看不懂

我只需要插入到数据库中。做需要的更新或删除操作。有什么解决方法吗?

那你需要更新还是不更新?好吧..如果您需要更新一堆行,请将它们与批量复制一起插入到临时表中,然后进行连接更新。


推荐阅读