在foreach循环内部和外部调用SaveChanges()之间的任何区别?

jaf*_*ffa 10 c# entity-framework

假设在循环内部对EF实体进行了更改,在foreach循环或循环外调用EF SaveChanges()之间是否存在任何性能优势/技术差异?

mar*_*c_s 28

是!

如果在循环内部调用它,EF将为每个单个实体写回数据库的更改(并且每个实体都将在其自己的单独事务中).

反过来,你将进行所有的更改,EF将在循环后立即将它们全部写回(在所有实体的单个事务中).

作为一般经验法则(实际上没有看到你的代码)尝试尽可能少的调用.SaveChanges().

一次调用50次更改通常比50次调用更好/更快/更有效,每次更改1次.

  • @fxdx:是的,你是对的 - 因为至少有一个错误(验证或其他),`.SaveChanges()`的整个操作将失败,并且不会将任何内容存储到数据库中 (3认同)
  • 新手问题 - 假设我在循环中创建了10个实体 - 其中9个是'有效'而另一个不是(例如Id = null) - 循环后调用SaveChanges()不会将任何实体保存到数据库中 - 是正确?任何人都要澄清 (2认同)
  • @marc_s - 如果我在循环中为每个项目发送电子邮件,那么如果我将 savechanges 放在循环之外,那么即使 savechanges 中可能出现问题,每次都会发送电子邮件。这要怎么处理呢? (2认同)

小智 9

另一个要做的是假设你的foreach循环遍历在DbContext中活动的EntitySet,你将得到一个System.Data.SqlClient.SqlException:另一个线程在会话中运行.

这是因为foreach实际上在另一个线程中运行,并且不允许事务完成.

除了上面的评论之外,更少的交易更好.

假设您有一个上下文数据库并执行以下操作:

var groups = from i in db.items select i.GroupNumber;
foreach( var grp in groups)
{
    //... do something
    db.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)

这将抛出异常

避免这种情况的解决方案(如果合适!!)是通过将第一行更改为:将实体集置于对象空间中来"实现"实体集:

var groups = (from i in db.items select i.GroupNumber).ToList();
Run Code Online (Sandbox Code Playgroud)

这将允许您保存在foreach(如果需要)