2013-08-11 4 views
21

Çok büyük bir veri kümesi, yaklaşık 2 milyon kayıt çalışıyorum. Aşağıdaki kodu aldım ancak yaklaşık 600.000 kayıt olmak üzere üç seride işlem yapıldıktan sonra bellek dışında bir istisna yapıyorum. Anladığım kadarıyla, her bir toplu varlık çerçevesinin tembel yükleri üzerinden geçiyor, ki bu da tam 2 milyon kaydı hafızada oluşturmaya çalışıyor. İşlediğim partiyi boşaltmanın herhangi bir yolu var mı?Varlık çerçevesi büyük veri kümesi, bellek istisnası yok

ModelContext dbContext = new ModelContext(); 
IEnumerable<IEnumerable<Town>> towns = dbContext.Towns.OrderBy(t => t.TownID).Batch(200000); 
foreach (var batch in towns) 
{ 
    SearchClient.Instance.IndexMany(batch, SearchClient.Instance.Settings.DefaultIndex, "Town", new SimpleBulkParameters() { Refresh = false }); 
} 

Not: https://code.google.com/p/morelinq/

arama istemci şudur: Toplu yöntemi bu proje geliyor https://github.com/Mpdreamz/NEST

+0

Büyük miktarlarda veri, ORM'nin uygun bir araç olduğundan emin olmadığım bir senaryodur ... – Vadim

+0

@Vadim ORM, iş mantığını temel veri deposu hakkında endişelenmeden işlemek için uygun bir araçtır, ancak ORM ile toplu işlem yazmanın daha kolay yolları vardır. –

+2

@AkashKava, elbette öyle. Gerçek şu ki, ORM'leri büyük hacimli verilerle birleştirdiğinizde, her zaman diğer senaryolardaki bir özelliği göz önünde bulunduracağınız her türlü ORM yönünü kendiniz “iptal” edersiniz. Diğer durumlarda, kodu, özellikle kullanmakta olduğunuz ORM sorunlarına yönelik bir şekilde yazarsınız. Tüm söylediğim - büyük hacimli veriler verildiğinde ORM'ler sorunlu hale geliyor. – Vadim

cevap

55

Sorun, EF veri aldığımda aslında iki kopya olmasıdır Veriler yaratıldı, biri kullanıcıya geri döndü, ve bir saniye içinde EF, değişiklik saptaması için kullandı ve kullanıldı (böylece veritabanında değişiklik yapmaya devam edebilir). EF, bu ikinci seti, bağlamın ömrü boyunca saklar ve bu ayar size hafızanın dışında kalmasını sağlar.

IEnumerable<IEnumerable<Town>> towns = dbContext.Towns.AsNoTracking().OrderBy(t => t.TownID).Batch(200000); 

bu EF söyler:

Bu

  1. başa 2 seçenek sorgu eg, içerik her parti
  2. Kullanım .AsNoTracking() yenilemek zorunda Değişiklik tespiti için bir kopyasını saklamamak. AsNoTracking'in ne yaptığı ve bunun performans üzerindeki etkileri hakkında blogumda biraz daha fazla bilgi edinebilirsiniz: http://blog.staticvoid.co.nz/2012/4/2/entity_framework_and_asnotracking

+0

NoTracking gezinme özelliklerini koruyor mu? Örneğin, ilgili nesneleri ayarlamak/eklemek istersem, kaydeder mi? –

+1

@AkashKava hayır, eğer bir şey kaydetmek istiyorsanız, ilk önce içeriği bağlama eklemeniz gerekecek, eğer varlığın gezinme özellikleri varsa, bunların da eklenmesi gerekecektir. Yüklediğiniz varlıkları gerçekten değiştirmek istiyorsanız, ilk yöntemi kullanmanızı öneriyorum. –

+2

Teşekkürler @LukeMcGregor, Ben her partide gerçekten iyi çalıştığı bağlamı yenilemeyi buldum –

İlgili konular