【问题标题】:What is the difference between AddRange and AddRangeAsync in EF CoreEF Core 中的 AddRange 和 AddRangeAsync 有什么区别
【发布时间】:2019-05-21 15:10:23
【问题描述】:
我正在使用 EF Core 插入条目,我注意到当我调试这行代码 context.MyEntityDbSet.AddRangeAsync(records) 时,加载需要一秒钟,而不是 context.MyEntityDbset.AddRange(records) 它会立即加载。调用AddRangeAsync 方法时是否发生了数据库调用?和AddRange 有什么不同吗?
【问题讨论】:
标签:
c#
.net-core
entity-framework-core
【解决方案1】:
根据官方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】:
很可能是的。来自文档:
此方法是异步的,仅允许特殊值生成器(例如“Microsoft.EntityFrameworkCore.Metadata.SqlServerValueGenerationStrategy.SequenceHiLo”使用的值生成器)异步访问数据库。对于所有其他情况,应使用非异步方法。
这意味着您不应该使用 AddRangeAsync,除非您使用需要在生成值之前访问数据库的值生成器之一。
使用 IDENTITY 或序列来提供键值不需要显式数据库访问。在表中插入行时生成键值
关于 HiLo
这是在客户端生成密钥的安全策略。服务器为每个 client 生成一个High 值,这就是需要数据库访问的原因。然后客户端开始增加一个“低”值并将其添加到服务器的高值以生成唯一键。这确保了两个客户永远不会创造相同的价值。
还可以让客户端在数据实际插入数据库之前就知道键值
不安全的策略 - MAX +1
一个几乎可以保证重复的不安全策略是计算一个键的最大值并从中开始递增。除了计算 MAX 的明显成本之外,多个客户端可以轻松读取相同的 MAX 值并开始创建重复值。
更糟糕的是,删除最新的行会创建与已删除的行具有相同值的新键。使用旧 ID 作为引用的任何其他表最终都会指向错误的行。