什么逻辑确定实体框架 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()更好的方法来维持订单?

什么逻辑确定实体框架 6 的插入顺序

  • 无法在 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)