2013-04-30 29 views
6
Ben F5'i kullanarak ve benim bağlamına POCO varlıkların bir bağlantısız grafiğini takılarak ediyorum

şey böyle yavaş: -Varlık Framework - "takın()"

using (var context = new MyEntities()) 
{ 
    context.Configuration.AutoDetectChangesEnabled = false; 

    context.MyEntities.Attach(myEntity); 

    // Code to walk the entity graph and set each entity's state 
    // using ObjectStateManager omitted for clarity .. 

    context.SaveChanges(); 
} 

varlık "myEntity" büyük olduğunu Pek çok çocuk koleksiyonuna sahip varlıkların grafiği, kendi çocuk koleksiyonlarına sahipler, vb. Grafiğin tamamı 10000 mertebesinde olmakla birlikte, sadece küçük bir sayı genellikle değişmektedir.

Varlık durumlarını ve geçerli SaveChanges() kodunu ayarlama kodu oldukça hızlıdır (< 200 ms). Buradaki problem bu Attach() ve 2,5 saniye sürüyor, bu yüzden geliştirilip geliştirilemeyeceğini merak ediyorum. Yukarıda yaptığım AutoDetectChangesEnabled = false'u ayarladığınızı söyleyen makaleler gördüm, ancak senaryoda hiçbir fark yaratmıyor. Bu neden?

cevap

2

10000 varlıklı bir nesne grafiği eklemek için 2,5 saniyenin "normal" olduğundan korkuyorum. Muhtemelen bu süreyi alan grafiği eklediğinizde gerçekleşen varlık anlık görüntüsü oluşturmasıdır.

"sadece küçük bir numarası genellikle değiştirilir" ise - örneğin, veritabanından özgün öğeleri yüklemek ve tüm grafik eklemek yerine kendi özelliklerini değiştirmek için düşünebiliriz - 100 ki:

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

Bu, çok sayıda veritabanı sorgusu oluşturacak olsa da, yalnızca gezinme özellikleri olmayan "düz" öğeler yüklenecek ve (Find numaralı telefon araması yapıldığında oluşan) çok zaman harcamayacaktır. sorgu sayısını azaltmak için ayrıca bir Contains sorgu kullanarak bir "toplu" olarak aynı türde varlıkları yüklemeye deneyebilirsiniz:

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

Size sadece sayısal özelliklerini değiştirmek zorunda varsayımı altında sadece basitleştirilmiş bir örnek varlıkların İlişkilerin modifikasyonları (çocuklar koleksiyonlara eklenmiş ve/veya silinmiş vb.) Söz konusu olduğunda, bu durum daha karmaşık hale gelebilir.

+0

Çok teşekkürler, bu bilmek yararlıdır. –