是什么原因导致.Attach()是缓慢EF4? [英] What causes .Attach() to be slow in EF4?

查看:238
本文介绍了是什么原因导致.Attach()是缓慢EF4?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们已经在我们的code通用的更新方法,做了

We have a generic update method in our code that does a

foreach (var entity in entityList)
{
    Context.GetIDbSet<T>().Attach(entity);
    Context.SetState(entity, EntityState.Modified);
}

我通过传递实体的枚举,每个实体调用这个曾经测试了这一点。

I'm testing this out by passing in an enumeration of entities and calling this once per entity.

什么我发现是,1000的实体的枚举大约需要47冲锋枪运行。
是预期的行为?或者是有什么毛病code段?

What I'm finding is that an enumeration of 1000 entities takes approximately 47s to run. Is that expected behavior? Or is there something wrong with the code snippet?

剖析表明attach()方法比SETSTATE()方法要慢。

Profiling showed the Attach() method was slower than the SetState() method.

我跑它是在50性质的实体的测试,如果有任何影响无关。

The test I ran it on was on an entity with 50 properties and no relations if that has any impact.

推荐答案

我可以证实这种缓慢的行为,我也发现了主要原因。我做了一个小测试与下面的模型......

I can confirm this slow behaviour and I also found the main reason. I've made a little test with the following model ...

public class MyClass
{
    public int Id { get; set; }
    public string P1 { get; set; }
    // ... properties P2 to P49, all of type string
    public string P50 { get; set; }
}

public class MyContext : DbContext
{
    public DbSet<MyClass> MyClassSet { get; set; }
}

...这个测试程序...

... and this test program ...

using (var context = new MyContext())
{
    var list = new List<MyClass>();
    for (int i = 0; i < 1000; i++)
    {
        var m = new MyClass()
        {
            Id = i+1,
            P1 = "Some text ....................................",
            // ... initialize P2 to P49, all with the same text
            P50 = "Some text ...................................."
        }
        list.Add(m);
    }

    Stopwatch watch = new Stopwatch();
    watch.Start();
    foreach (var entity in list)
    {
        context.Set<MyClass>().Attach(entity);
        context.Entry(entity).State = System.Data.EntityState.Modified;
    }
    watch.Stop();
    long time = watch.ElapsedMilliseconds;
}


测试1

正是code以上:

- > 时间为29.2秒

测试2

注释掉该行...

//context.Entry(entity).State = System.Data.EntityState.Modified;

- > 时间为15.3秒

测试3

注释掉该行...

//context.Set<MyClass>().Attach(entity);

- > 时间为57.3秒

这结果是很奇怪的,因为我预计,调用连接是没有必要的,因为改变状态反正重视。

This result is very strange because I expected that calling Attach is not necessary because changing the state attaches anyway.

测试4

删除属性P6到P50(所以我们只有在实体5串),原来的code:

Remove properties P6 to P50 (so we only have 5 strings in the entity), original code:

- > 时间= 3,4秒

所以,是的,性能显着数量的严重事项。

So, yes, obviously the number of properties strongly matters.

测试5

在循环之前(型号与所有50个媒体再次)添加以下行:

Add the following line before the loop (model again with all 50 properties):

context.Configuration.AutoDetectChangesEnabled = false;

- > 时间= 1,4秒

测试6

再次与 AutoDetectChangesEnabled = FALSE ,但只有5个属性:

Again with AutoDetectChangesEnabled = false but with only 5 properties:

- > 时间= 1,3秒

所以,不改变跟踪属性的数量并不重要那么多了。

So, without change tracking the number of properties doesn't matter so much anymore.

结论

到目前为止,大部分的时间似乎花费了更改跟踪机制采取附加对象属性的快照。如果您不需要它禁用更改您$ C $追踪ç片段。 (我猜你的code你真的不需要改变由entitiy的状态设置为修改你基本上标记的所有的属性,因为跟踪作为反正变了。所以的所有的列被发送到一个更新语句的数据库。)

By far most of the time seems to be spent for taking the snapshot of the attached object's properties by the change tracking mechanism. If you don't need it disable change tracking for your code snippet. (I guess in your code your really don't need change tracking because by setting the entitiy's state to Modified you basically mark all properties as changed anyway. So all columns get sent to the database in an update statement.)

修改

上面的测试时间是在调试模式下。但释放模式不会有很大的不同(例如:测试1 = 28,7秒,测试5 = 0.9秒)。

The test times above are in Debug mode. But Release mode doesn't make a big difference (for instance: Test 1 = 28,7 sec, Test 5 = 0,9 sec).

这篇关于是什么原因导致.Attach()是缓慢EF4?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆