【发布时间】:2020-08-13 13:22:19
【问题描述】:
我有很多行(300k+)要在最短的时间内插入到 SQL Server 数据库中,所以我的想法是使用并行化和分区数据并使用异步将数据泵入 SQL,X 线程在时间,每个上下文 100 行,上下文被回收以最小化跟踪开销。但是,这意味着要并行使用多个连接,因此 CommittableTransaction/TransactionScope 将使用分布式事务,这将导致并行事务登记操作返回臭名昭著的 "This platform does not support distributed transactions." 异常。
我确实需要提交/回滚整个 upsert 集的能力。它是批量上传过程的一部分,任何错误都应将更改回滚到以前的工作/稳定条件,应用程序明智。
我有哪些选择?只用一个连接不并行化?
注意:问题并不像一批插入命令那么简单,如果是这样的话,我会生成插入并在服务器上运行它们作为查询或确实使用SqlBulkCopy。其中大约一半是更新,一半是插入,其中新键由 SQL Server 生成,需要获取并在接下来插入的子对象上重新设置键,行分布在 3 级层次结构中的大约十几个表中.
【问题讨论】:
-
创建选项可以做的一件大事是从 IDENTITY 切换到序列以生成密钥。序列支持客户端键生成,因此您可以对整个对象图进行键控。然后,您可以按外键顺序批量加载或暂存/合并表。见docs.microsoft.com/en-us/sql/relational-databases/…
-
有没有办法用表键来做到这一点并将其与
IDENTITY_INSERT ON结合起来? -
EF Core 支持序列,但它们在 SQL Server 中设置为列默认值,而不是 IDENTITY 列。因此,您可以根据需要提前生成密钥。 IDENTITY_INSERT 的问题(当然有几个),但这里最大的问题是无法提前生成键值。见docs.microsoft.com/en-us/ef/core/modeling/sequences
-
这是一个很好的提示,谢谢,我一定会在以后的数据库中记住这一点。但是,这个不在我们的控制之下,它是一个生产数据库,并且模式更改是不行的,特别是因为有其他系统在使用它。风险管理会砍掉我的头:)
标签: c# sql-server entity-framework .net-core task-parallel-library