0

我想知道为什么使用 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();
            }
        }
4

1 回答 1

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 提供程序的实体框架行为将很有用:

// 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 将启动一个漫长的过程来检查(更改与否?)每个对象的每个属性的值。

于 2011-09-07T08:14:08.813 回答