EF Core中AddRange和AddRangeAsync有什么区别

时间:2019-05-21 15:10:24

标签: c# .net-core entity-framework-core

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

3 个答案:

答案 0 :(得分:5)

很有可能是。从文档中:

  

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

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

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

关于HiLo

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

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

不安全策略-MAX +1

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

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

答案 1 :(得分:2)

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

答案 2 :(得分:-1)