Alex Rivera | Logout

What causes .Attach() to be slow in EF4?

Asked 2011-05-06T22:04:49.547
28

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.

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?

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

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

Edit
Report

1 Answer

71

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;
}

Test 1

Exactly the code above:

--> time = 29,2 sec


Test 2

Comment out the line ...

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

--> time = 15,3 sec


Test 3

Comment out the line ...

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

--> time = 57,3 sec

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


Test 4

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

answered 2011-05-07T13:06:28.093

Your Answer