41

वर्तमान में जब मैं एक प्रश्न है कि डब्ल्यू/पेजिंग उपयोग किया जाएगा चलाने की आवश्यकता मैं यह कुछ इस तरह करते हैं:डेटा के एक पृष्ठ से पूछने के लिए बेहतर तरीका और इकाई ढांचे 4.1 में कुल गिनती प्राप्त करें?

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

यह काम करता है, लेकिन मैंने सोचा अगर यह संभव है इस जबकि अभी भी अधिक कुशल होने का सुधार करने के लिए linq का उपयोग कर? मैं संग्रहीत प्रो का उपयोग कर डीबी डब्ल्यू/ओ की एक यात्रा में गिनती w/डेटा पुनर्प्राप्ति को गठबंधन करने का एक तरीका नहीं सोच सका।

+1

पर एक नजर डालें [मैं कुल रिकॉर्ड गिनती और मेरी सेवा परत विधि से पृष्ठांकित अभिलेखों का IEnumable संग्रह का पर्दाफाश करना चाहिए कैसे?] (Http://stackoverflow.com/questions/6417886/how-should-i-expose- कुल-रिकॉर्ड-गिनती-और-Ienumable-संग्रह-of-paged-reco/6418761 # 6418761) – Eranga

+0

दिलचस्प है, लेकिन ऐसा लगता है कि मैं क्या कर रहा हूं। यह डेटाबेस में 2 अलग-अलग कॉल करता है। कुल संख्या के लिए एक और डेटा पेज के लिए दूसरा। –

+3

ईएफ में भविष्य में प्रश्न नहीं हैं जैसे nHibernate। यह डेटाबेस में 2 यात्राओं ले जाएगा। – Eranga

उत्तर

65

निम्न क्वेरी को डेटाबेस के लिए एक यात्रा में गिनती और पृष्ठ परिणाम मिलेंगे, लेकिन यदि आप LINQPad में SQL को चेक करते हैं, तो आप देखेंगे कि यह बहुत सुंदर नहीं है। मैं केवल कल्पना कर सकता हूं कि यह एक और जटिल क्वेरी के लिए कैसा दिखता है।

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

इस तरह एक सरल प्रश्न के लिए, तो आप शायद किसी भी विधि और अधिक अंतर न (डेटाबेस, या GroupBy का उपयोग कर 1 यात्रा में यह करने के लिए करने के लिए 2 यात्राएं) इस्तेमाल कर सकते हैं। किसी भी जटिल के लिए, मुझे लगता है कि एक संग्रहित प्रक्रिया सबसे अच्छा समाधान होगा।

+4

+1, अच्छा! मैंने सोचा नहीं था कि यह बिल्कुल संभव है। – Slauma

+12

यदि तालिका में कोई रिकॉर्ड नहीं है तो यह एक त्रुटि फेंक देगा। इसे हल करने के लिए, बस। फर्स्ट() को .irstOrDefault() के साथ प्रतिस्थापित करें और यह जांचना याद रखें कि परिणाम शून्य नहीं है या नहीं। –

+0

मुझे भी एक ही समस्या है क्योंकि मैंने वर्तमान में DAPPER का उपयोग किया है और इसमें एकल कॉल में कई प्रश्नों को पुनर्प्राप्त करने के लिए कई विकल्प पूछे गए हैं। एड्रिफ्ट समाधान प्रशंसनीय चुड़ैल है, मुझे पहले से ही लगता है कि यह ईएफ में संभव नहीं था। बहुत धन्यवाद adrift। – Prageeth

2

मैं सुझाव देता हूं कि पहले पृष्ठ के लिए दो प्रश्न, कुल गणना के लिए एक और पहले पृष्ठ या परिणामों के लिए एक।

उपयोग के लिए कुल गणना कैश करें जब आप पहले पृष्ठ से आगे बढ़ते हैं।

+2

कुल कैशिंग असंगतता पैदा कर सकता है, यदि पहले और बाद के पेज कॉल के बीच रिकॉर्ड की संख्या –

+1

के बीच बदल जाती है, लेकिन अक्सर इससे कोई फर्क नहीं पड़ता, खासकर यदि परिणाम की कई आयुएं हैं। जब मुझे गिनती की आवश्यकता होती है और परिणाम मिलते हैं तो एक प्रश्न बहुत धीमी और दो प्रश्नों की तुलना में पढ़ने में मुश्किल होती है। – Bryan

+0

बस सुनिश्चित करें कि आपकी कैश की कुल गणना किसी भी खंड के लिए विशेष रूप से कैश की गई है। यदि आपकी पहली क्वेरी 'ctx.Popleople है। (पी => p.Name.StartsWith (" ए ")) ', आप अगली क्वेरी' ctx.Popleople पर कुल गणना का पुन: उपयोग नहीं करना चाहते हैं। (पी => p.Name.StartsWith ("बी")) ' – xr280xr

संबंधित मुद्दे