什么逻辑确定实体框架 6 的插入顺序
本文关键字:插入 顺序 框架 实体 什么 | 更新日期: 2023-09-27 18:30:29
所以,我有一个DBContext,我正在执行以下操作:
dbContext.SomeTables1.Add(object1)
dbContext.SomeTables2.AddRange(objectArray2)
dbContext.SomeTables3.AddRange(objectArray3)
dbContext.SaveChanges();
EF 不会按此顺序插入数据库记录,而是按随机顺序插入它们。要以相同的顺序插入它们,我必须在每次添加后进行dbContext.SaveChanges()
。这不是一个有效的解决方案,就我而言,完成所有插入需要 10 秒,而一次保存的随机订单大约需要 3 秒。
:注:我需要正确的顺序来解决死锁问题。
我的问题是:
- 此问题是否已在 EF7 中解决?
- 我可以分析 EF 并确定随机顺序,但是,是否可以保证它将始终具有相同的随机顺序或 它在请求之间会发生变化吗?(如果 对这个问题的回答是肯定的)。
- 有没有比每次添加
dbContext.SaveChanges()
更好的方法来维持订单?
- 无法在 EF6 或 EF Core 中指定保存顺序
- 此问题在 EF Core 中未解决,因为这不是问题。
- 如果前置任务相同,则顺序将相同(这种情况可能很少发生)
当您调用 SaveChanges 时,所有实体都按方法"ProduceDynamicCommand"中的内部顺序排序,然后由方法"TryTopologicalSort"再次排序,该方法循环添加没有前置命令的命令(如果添加 A 和 B 并且 A 依赖于 B,则 B 将插入 A 之前)
您可以按批量添加进行插入。
由于执行插入需要 3 秒,因此我假设您有数千个实体,执行批量插入可能会提高您的性能,从而将 10 秒减少到更少,然后可能是最初的 3 秒!
为了提高您的性能,您可以使用 http://entityframework-extensions.net/(付费但支持所有情况)
免责声明:我是实体框架扩展项目的所有者。
我已经找到了一种方法。它只是想我会让你知道:
using (var dbContextTransaction = Context.Database.BeginTransaction())
{
dbContext.SomeTables1.Add(object1);
dbContext.SaveChanges();
dbContext.SomeTables1.Add(object2);
dbContext.SaveChanges();
dbContextTransaction.Commit();
}
若要在 EF 和 EF Core 的标识列中显式设置主键的值(以及聚集索引的顺序),需要在调用 _context.SaveChanges()
之前手动打开IDENTITY_INSERT
,之后需要关闭IDENTITY_INSERT
,如下所示:此示例假定 EF Core
// Add your items with Identity Primary Key field manually set
_context.SomeTables1.AddRange(yourItems);
_context.Database.OpenConnection();
try {
_context.Database.ExecuteSqlRaw("SET IDENTITY_INSERT dbo.SomeTables1 ON");
_context.SaveChanges();
_context.Database.ExecuteSqlRaw("SET IDENTITY_INSERT dbo.SomeTables1 OFF");
} finally {
_context.Database.CloseConnection();
}
我找到了一个非常简单的解决方案。
只需将实体的 ID(主键)的属性设置为与所需顺序匹配的值即可。SaveChanges() 首先按此 ID 排序,然后按其他属性排序。分配的 ID 可能已存在于数据库中。写入数据库时会分配一个唯一的 ID。
for(int i = 0; i < objectArray2.Count(); i++)
{
objectArray2[i].Id = i;
}
dbContext.SomeTables2.AddRange(objectArray2)