15

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

4

4 回答 4

37

是的!

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

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

作为一般经验法则(实际上没有看到您的代码),尽量减少调用.SaveChanges()次数。

一次调用 50 次更改通常比 50 次调用每次更改 1 次要好得多/更快/更有效率。

于 2012-06-21T08:27:42.960 回答
12

另一个要说明的是,假设您的 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();
}

这将抛出异常

避免这种情况的解决方案(如果合适!!)是通过将第一行更改为:

var groups = (from i in db.items select i.GroupNumber).ToList();

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

于 2014-12-10T15:42:48.980 回答
2

在循环之外,将只创建一个事务来更新数据库,而另一个为每次迭代创建一个事务。因为 EF 使用工作单元模式,它将所有更改保存在内存中,并且在 SaveChanges 方法中,它保存了您对数据库所做的所有更改。

于 2012-06-21T08:27:18.803 回答
1

性能会有所不同,在循环内,您将在每次迭代时调用数据库。在循环之外,您将调用数据库一次。根据您的迭代次数,这可能会在性能上产生巨大差异。

于 2012-06-21T08:28:21.527 回答