我想知道为什么使用POCO和Devart DotConnect for Oracle,代码片段1比代码2更快。
我尝试了超过100000条记录而代码1的速度比2快。为什么?我认为“SaveChanges”会清除缓冲区,因为只有1个连接,它会更快。我错了吗?
代码1:
for (var i = 0; i < 100000; i++)
{
using (var ctx = new MyDbContext())
{
MyObj obj = new MyObj();
obj.Id = i;
obj.Name = "Foo " + i;
ctx.MyObjects.Add(obj);
ctx.SaveChanges();
}
}
代码2:
using (var ctx = new MyDbContext())
{
for (var i = 0; i < 100000; i++)
{
MyObj obj = new MyObj();
obj.Id = i;
obj.Name = "Foo " + i;
ctx.MyObjects.Add(obj);
ctx.SaveChanges();
}
}
答案 0 :(得分:3)
第一个代码段工作得更快,因为每次从池中获取相同的连接,因此重新打开时不会有性能损失。
在第二种情况下,逐渐将100000个对象添加到上下文中。使用基于快照的慢速跟踪(如果没有动态代理)。这导致检测每个SaveChanges()上是否发生任何缓存对象的任何更改。每次后续迭代都会花费越来越多的时间。
我们建议您尝试以下方法。它应该比上面提到的更好:
using (var ctx = new MyDbContext())
{
for (var i = 0; i < 100000; i++)
{
MyObj obj = new MyObj();
obj.Id = i;
obj.Name = "Foo " + i;
ctx.MyObjects.Add(obj);
}
ctx.SaveChanges();
}
修改强>
如果您使用在一个SaveChanges()中执行大量操作的方法,那么另外配置Devart dotConnect for Oracle提供程序的Entity Framework行为将非常有用:
// Turn on the Batch Updates mode:
var config = OracleEntityProviderConfig.Instance;
config.DmlOptions.BatchUpdates.Enabled = true;
// If necessary, enable the mode of re-using parameters with the same values:
config.DmlOptions.ReuseParameters = true;
// If object has a lot of nullable properties, and significant part of them are not set (i.e., nulls), omitting explicit insert of NULL-values will decrease greatly the size of generated SQL:
config.DmlOptions.InsertNullBehaviour = InsertNullBehaviour.Omit;
这里只提到了一些选项。它们的完整列表可在我们的文章中找到: http://www.devart.com/blogs/dotconnect/index.php/new-features-of-entity-framework-support-in-dotconnect-providers.html
我错误地认为当调用SaveChanges()时,所有的 缓存中的对象存储到DB并清除缓存,因此每个 循环是独立的吗?
SaveChanges()发送并提交对数据库的所有更改,但对附加到上下文的所有实体继续进行更改跟踪。如果使用基于快照的更改跟踪,新的SaveChanges将启动一个长时间的检查(更改与否?)每个对象的每个属性值的过程。