41

Şu ben o böyle bir şey yapmak:Bir veri sayfasını sorgulamak ve varlık çerçevesindeki toplam sayımı elde etmenin daha iyi bir yolu 4.1? I/çağrı w kullanılacak bir sorgu çalıştırmak için gerektiğinde

//Setup query (Typically much more complex) 
var q = ctx.People.Where(p=>p.Name.StartsWith("A")); 

//Get total result count prior to sorting 
int total = q.Count();  

//Apply sort to query 
q = q.OrderBy(p => p.Name); 

q.Select(p => new PersonResult 
{ 
    Name = p.Name 
}.Skip(skipRows).Take(pageSize).ToArray(); 

Bu çalışır, ancak bu süre daha da verimli olmasını iyileştirmek mümkün olup olmadığını merak linq kullanarak? Kayıtlı bir proc kullanarak DB w/o'ya tek seferde veri w/veri alma ile birleştirmek için bir yol düşünemiyorum.

+1

bir göz atın [I toplam kayıt sayısı ve benim hizmet tabaka yönteminden disk belleği kayıtların IEnumable koleksiyonunu göstermelidir nasıl?] (Http://stackoverflow.com/questions/6417886/how-should-i-expose- toplam kayıt-sayma-ve-ienumable-koleksiyon-of-paged-reco/6418761 # 6418761) – Eranga

+0

İlginç, ama yaptığım ile aynı görünüyor. Veritabanına 2 farklı çağrı yapar. Veri sayfası için toplam sayım ve diğeri. –

+3

EF, nHibernate gibi gelecek sorgulara sahip değil. Veritabanına 2 yolculuk sürecek. – Eranga

cevap

65

aşağıdaki sorgu veritabanına bir gezi sayısı ve sayfa sonuç verecektir, ancak LINQPad içinde SQL kontrol ederseniz, bunu çok güzel olmadığını göreceksiniz. Sadece daha karmaşık bir sorgu için neye benzeyeceğini hayal edebiliyorum.

var query = ctx.People.Where (p => p.Name.StartsWith("A")); 

var page = query.OrderBy (p => p.Name) 
       .Select (p => new PersonResult { Name = p.Name })   
       .Skip(skipRows).Take(pageSize) 
       .GroupBy (p => new { Total = query.Count() }) 
       .First(); 

int total = page.Key.Total; 
var people = page.Select(p => p); 

bu gibi basit bir sorgu için, muhtemelen yöntemi ve çok fark yok (veritabanı ya da 1 gezisi yapmak GroupBy kullanmanın 2 gezileri) ya kullanabilirsiniz. Karmaşık bir şey için, saklı bir prosedürün en iyi çözüm olacağını düşünüyorum.

+4

+1, Nice! Bunun mümkün olduğunu düşünmemiştim. – Slauma

+12

Tablonun kaydı yoksa bir hata verir. Bunu çözmek için, .FirstOrDefault() ile .First() dosyasını değiştirin ve sonucun boş olup olmadığını kontrol etmeyi unutmayın. –

+0

Ben de aynı sorunu var çünkü şu anda DAPPER kullandım ve tek bir çağrı birden çok sorgu almak için sorgu birden çok seçenek var.adrift çözüm takdire şayan cadı Ben zaten EF mümkün olmadığını düşünüyorum. çok teşekkür ederim. – Prageeth

2

İlk sayfa için iki sorgu, toplam sayım için bir ve ilk sayfa veya sonuçlar için bir tane yapıyor öneririz.

İlk sayfanın ötesine geçerken kullanmak için toplam sayımı önbelleğe alın.

+2

Toplam önbelleğe alma tutarsızlığı neden olabilir, ilk ve sonraki sayfa –

+1

çağrıları arasında değişen kayıtların sayısı değişebilir, ancak çoğu zaman, özellikle sonuçların çok yaş varsa, önemli değil. Sayıma ve sonuca ihtiyaç duyduğumda tek bir sorgu iki sorgu ile karşılaştırıldığında çok yavaş ve okunması zordu. – Bryan

+0

Önbelleğe alınan toplam sayınızın özellikle herhangi bir yerde tümce için önbelleğe alındığından emin olun. İlk sorgunuz 'ctx.People.Where ise (p => p.Name.StartsWith (" A "))', bir sonraki sorgudaki toplam sayımı tekrar kullanmak istemezsiniz 'ctx.People.Where (p => p.Adı.StartsWith ("B")) ' – xr280xr

İlgili konular