2013-02-12 25 views
14

मैं .NET पर थोड़ी नौसिखिया हूं, और मैं सोच रहा था कि linq कैसे काम करता है, क्योंकि आप कई linq प्रश्नों का पालन कर सकते हैं, एक के बाद एक, लेकिन उनमें से कोई भी वास्तव में निष्पादित नहीं किया जाता है जब तक कि उन्हें जानकारी स्थानांतरित करने या परिवर्तित करने के लिए उपयोग नहीं किया जाता सूची, आदि
IQueryable<T> का उपयोग करके, linq क्वेरी प्राप्त करने के 2 महत्वपूर्ण तरीके हैं, जो दर्शाता है कि एसक्यूएल पर सीधे फ़िल्टर कहां है, और आईनेमेरेबल जो सभी रिकॉर्ड्स प्राप्त करते हैं और फिर यह स्मृति पर उनके साथ काम करते हैं।एक IQueryable linq क्वेरी को IENumerable <T> में कनवर्ट करने के लिए linq अनुकूलित तरीके से रद्द करता है?

  //Linq dynamic library 
      IQueryable<Table> myResult = db.Categories 
       .Where(a => a.Name.Contains(StringName)) 
       .OrderBy("Name") 
       .Skip(0) 
       .Take(10); 

      if (myResult != null) 
      { 
       return myResult.AsEnumerable(); 
      } 
      else 
      { return null; } 

Depsite मैं LINQ गतिशील पुस्तकालय का उपयोग कर रहा है, इस क्वेरी से सीधा परिणाम IQueryable<T> पर प्राप्त किया जा रहा है, यदि क्वेरी अंत में IEnumerable रूप में वापस आ जा रहा है, यह है: हालांकि, के लिए इस कोड पर एक नज़र डालें सचमुच एसक्यूएल पर फ़िल्टर किया जा रहा है? या यह स्मृति में है?

+1

इसका उत्तर देने का सबसे अच्छा तरीका डेटा संदर्भ की 'लॉग' संपत्ति को देखना और स्वयं के लिए देखना है। अपनी क्वेरी पर विभिन्न भिन्नताओं के साथ प्रयोग करें और देखें कि यह वास्तव में * निष्पादित * को कैसे प्रभावित करता है। – Servy

+0

मुझे खेद है, मैं लॉग कैसे देखूं? –

+1

ठीक है, यह शायद उस प्रकार की उस संपत्ति के लिए Google, या एमएसडीएन दस्तावेज़ के लिए एक अच्छा सवाल है; अगर मेमोरी परोसता है तो वहां एक अच्छा उदाहरण है। – Servy

उत्तर

28

यह अभी भी डेटाबेस में निष्पादित करने जा रहा है, चिंता न करें। असल में यह सब नीचे है कि Where आदि के कार्यान्वयन का उपयोग किया जाता है। जबकि आप IQueryable<T> पर विधियों को कॉल कर रहे हैं - Queryable एक्सटेंशन विधियों के माध्यम से - यह अभिव्यक्ति पेड़ का उपयोग करेगा। जब आप उस क्वेरी से लाने के लिए प्रारंभ करते हैं, तो इसे SQL में बदल दिया जाएगा और डेटाबेस में भेजा जाएगा।

दूसरी ओर, यदि आप के बाद आप एक IEnumerable<T> के रूप में यह मिल गया है (संकलन समय प्रकार के संदर्भ में) उन तरीकों में से किसी का उपयोग करें, कि Enumerable में विस्तार विधियों का उपयोग करेगा, और के सभी शेष प्रसंस्करण प्रक्रिया में किया जाएगा।

उदाहरण के लिए, इस पर विचार करें:

var query = db.People 
       .Where(x => x.Name.StartsWith("J")) 
       .AsEnumerable() 
       .Where(x => x.Age > 20); 

यहाँ AsEnumerable()सिर्फ अपने इनपुट अनुक्रम दिखाए, लेकिन IEnumerable<T> के रूप में लिखा है। इस मामले में, डेटाबेस क्वेरी केवल उन लोगों को वापस कर देगी जिनके नाम J से शुरू हुए - और उसके बाद आयु फ़िल्टरिंग क्लाइंट पर की जाएगी।

+1

उत्तर के लिए बहुत बहुत धन्यवाद! उन्होंने बहुत मदद की! –

4

यदि आप IEnumerable<T> लौटाते हैं और फिर क्वेरी को परिशोधित करते हैं, तो स्मृति में और परिशोधन होता है। IQueryable<T> पर व्यक्त किया गया हिस्सा एप्राइपिएट एसक्यूएल स्टेटमेंट्स (LINQ-to-SQL केस के लिए, स्पष्ट रूप से) में अनुवादित होगा।

अधिक से अधिक विस्तृत उत्तर के लिए Returning IEnumerable<T> vs. IQueryable<T> देखें।