Entity Framework - “Attach()” is slow

前端 未结 1 1714
灰色年华
灰色年华 2021-01-18 12:05

I\'m using EF5 and attaching a disconnected graph of POCO entities to my context, something like this:-

using (var context = new MyEntities())
{
    context.         


        
相关标签:
1条回答
  • 2021-01-18 13:02

    I am afraid that 2,5 sec for attaching an object graph with 10000 entities is "normal". It's probably the entity snapshot creation that takes place when you attach the graph that takes this time.

    If "only a small number are usually changed" - say 100 - you could consider to load the original entities from the database and change their properties instead of attaching the whole graph, for example:

    using (var context = new MyEntities())
    {
        // try with and without this line
        // context.Configuration.AutoDetectChangesEnabled = false;
    
        foreach (var child in myEntity.Children)
        {
            if (child.IsModified)
            {
                var childInDb = context.Children.Find(child.Id);
                context.Entry(childInDb).CurrentValues.SetValues(child);
            }
            //... etc.
        }
        //... etc.
    
        context.SaveChanges();
    }
    

    Although this will create a lot of single database queries, only "flat" entities without navigation properties will be loaded and attaching (that occurs when calling Find) won't consume much time. To reduce the number of queries you could also try to load entities of the same type as a "batch" using a Contains query:

        var modifiedChildIds = myEntity.Children
            .Where(c => c.IsModified).Select(c => c.Id);
    
        // one DB query
        context.Children.Where(c => modifiedChildIds.Contains(c.Id)).Load();
    
        foreach (var child in myEntity.Children)
        {
            if (child.IsModified)
            {
                // no DB query because the children are already loaded
                var childInDb = context.Children.Find(child.Id);
                context.Entry(childInDb).CurrentValues.SetValues(child);
            }
        }
    

    It's just a simplified example under the assumption that you only have to change scalar properties of the entities. It can become arbitrarily more complex if modifications of relationships (children have been added to and/or deleted from the collections, etc.) are involved.

    0 讨论(0)
提交回复
热议问题