假设对循环内的EF实体进行了更改,在foreach循环或循环外调用EF SaveChanges()之间是否有任何性能优势/技术差异?
答案 0 :(得分:22)
是!
如果您在循环内部调用它,EF会将对每个实体的数据库的更改写回(并且每个实体都将在其自己的单独事务中)。
反过来说,你将进行所有的更改,EF会在循环后将它们一次性写回一次(在所有实体的一次交易中)。
作为一般经验法则(实际上没有看到您的代码)尝试尽可能少地调用.SaveChanges()
。
一次调用50次更改通常比50次调用更好/更快/更有效,每次更改1次。
答案 1 :(得分:7)
要做的另一个注意事项是假设你的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(如果需要)
答案 2 :(得分:2)
在循环外,循环将只创建一个事务来更新数据库,而另一个事务为每次迭代创建一个事务。因为EF使用工作单元模式来保存内存中的所有更改,并且在SaveChanges方法中它保存了您对数据库所做的所有更改。
答案 3 :(得分:1)
性能将不同,在循环内,您将在每次尝试时调用数据库。在外部循环,您将调用数据库一次。根据您的操作次数,这可以使性能产生巨大差异。