EF Core中AddRange和AddRangeAsync有什么区别

Ang*_*hev 5 c# entity-framework-core .net-core

我正在使用EF Core插入条目,并且我注意到,当我调试此代码行时,context.MyEntityDbSet.AddRangeAsync(records)加载它需要一秒钟,而不是context.MyEntityDbset.AddRange(records)立即发生。调用AddRangeAsync方法时是否发生数据库调用?有什么不同AddRange吗?

Pan*_*rov 7

根据官方的EF Core 文档 AddRangeAsync(IEnumerable<TEntity>, CancellationToken),应该与需要数据库往返的特殊值生成器一起使用。例如,如果您使用SqlServerValueGenerationStrategy.SequenceHiLo预先分配 ID 块,当 EF 跟踪新实体时,它可能需要首先查询数据库并询问新的“Hi”(有关 Hi/Lo 算法的更多信息可以在这里找到什么是Hi/Lo 算法?)。因此,当想法只是将实体设置为Added状态并且SqlServerValueGenerationStrategy.SequenceHiLo不需要时,AddRange使用。


Pan*_*vos 5

很有可能。从文档:

此方法是异步的,仅允许特殊值生成器(例如“ Microsoft.EntityFrameworkCore.Metadata.SqlServerValueGenerationStrategy.SequenceHiLo”使用的生成器)异步访问数据库。对于所有其他情况,应使用非异步方法。

这意味着除非您使用在生成值之前需要访问数据库的那些值生成器之一,否则不应该使用AddRangeAsync。

使用IDENTITY或序列提供键值不需要显式的数据库访问。当将行插入表中时生成键值

关于HiLo

这是在客户端生成密钥的安全策略。服务器High为每个客户端生成一个值,这就是为什么需要数据库访问的原因。然后,客户端开始增加“低”值并将其添加到服务器的高值中以生成唯一密钥。这样可以确保两个客户端永远不会创建相同的值。

它还允许客户端在将数据实际插入数据库之前知道键值

不安全策略-MAX +1

几乎可以保证重复的不安全策略是计算密钥的最大值并从该值开始递增。除了计算MAX的明显成本外,多个客户端还可以轻松读取相同的MAX值并开始创建重复值。

更糟糕的是,删除最新行将创建具有与已删除行相同值的新键。使用旧ID作为引用的任何其他表最终都将指向错误的行。