पहले बहुत कुछ कहा गया है, लेकिन जड़ों तक वापस, अधिक तकनीकी तरीके से:
IEnumerable
स्मृति में वस्तुओं का एक संग्रह है जिसे आप गणना कर सकते हैं - एक इन-मेमोरी अनुक्रम जो इसके माध्यम से पुनरावृति करना संभव बनाता है (यह foreach
लूप के लिए आसान रास्ता बनाता है , हालांकि आप IEnumerator
केवल साथ जा सकते हैं )। वे स्मृति में रहते हैं।
IQueryable
एक अभिव्यक्ति पेड़ है जो अंतिम परिणाम पर गणना करने की क्षमता के साथ कुछ बिंदु पर कुछ और में अनुवाद किया जाएगा । मुझे लगता है कि यह वही है जो ज्यादातर लोगों को भ्रमित करता है।
वे स्पष्ट रूप से विभिन्न अर्थ हैं।
IQueryable
एक अभिव्यक्ति ट्री (एक क्वेरी, बस) का प्रतिनिधित्व करता है जिसे अंतर्निहित क्वेरी प्रदाता द्वारा कुछ और के लिए अनुवाद किया जाएगा जैसे ही रिलीज एपीआई को बुलाया जाता है, जैसे कि LINQ एग्रीगेट फ़ंक्शन (सम, काउंट, आदि) या टोलिस्ट [एरे, डिक्शनरी]। ..]। और IQueryable
ऑब्जेक्ट भी लागू होते हैं IEnumerable
, IEnumerable<T>
ताकि यदि वे किसी क्वेरी का प्रतिनिधित्व करते हैं , तो उस क्वेरी का परिणाम पुनरावृत्त हो सके। इसका मतलब है कि IQueryable को केवल पूछताछ करने की आवश्यकता नहीं है। सही शब्द वे अभिव्यक्ति पेड़ हैं ।
अब उन अभिव्यक्तियों को कैसे निष्पादित किया जाता है और वे जो मोड़ लेते हैं, वह तथाकथित क्वेरी प्रदाताओं (अभिव्यक्ति निष्पादकों को हम उनके बारे में सोच सकते हैं) तक है।
में इकाई की रूपरेखा दुनिया (जो कि रहस्यमय अंतर्निहित डेटा स्रोत प्रदाता, या क्वेरी प्रदाता है) IQueryable
भाव देशी में अनुवाद किया T-SQL प्रश्नों। Nhibernate
उनके साथ भी ऐसी ही बातें करता है। आप LINQ में वर्णित अवधारणाओं को अच्छी तरह से अनुसरण करते हुए अपना एक लिख सकते हैं : उदाहरण के लिए, एक IQueryable प्रदाता लिंक का निर्माण , और आप अपने उत्पाद स्टोर प्रदाता सेवा के लिए एक कस्टम क्वेरी API चाहते हो सकता है।
इसलिए मूल रूप से, IQueryable
वस्तुओं का निर्माण तब तक हो रहा है जब तक हम उन्हें स्पष्ट रूप से जारी नहीं करते हैं और सिस्टम को उन्हें एसक्यूएल या जो कुछ भी फिर से लिखने और आगे की प्रक्रिया के लिए निष्पादन श्रृंखला नीचे भेजने के लिए कहते हैं।
जैसे कि निष्पादन को स्थगित करने के लिए यह LINQ
स्मृति में अभिव्यक्ति ट्री योजना को रखने और इसे केवल मांग पर निष्पादन में भेजने की सुविधा है, जब भी कुछ एपीआई को अनुक्रम के खिलाफ कहा जाता है (एक ही गणना, टोलिस्ट, आदि)।
विशिष्ट मामले के लिए आपके द्वारा किए जा रहे कार्यों पर दोनों का भारी उपयोग निर्भर करता है। जाने-माने रिपॉजिटरी पैटर्न के लिए मैं व्यक्तिगत रूप से वापस लौटने का विकल्प चुनता हूं IList
, जो IEnumerable
लिस्ट (इंडेक्स और लाइक) से अधिक है। तो यह मेरी सलाह है IQueryable
कि कोड में कहीं और केवल रिपॉजिटरी और IEnumerable के भीतर उपयोग करें । परीक्षणनीय चिंताओं के बारे में नहीं कहना जो IQueryable
टूट जाती है और चिंताओं के सिद्धांत को अलग कर देती है । यदि आप रिपॉजिटरी के भीतर से एक अभिव्यक्ति लौटाते हैं तो उपभोक्ता दृढ़ता की परत के साथ खेल सकते हैं।
गड़बड़ करने के लिए एक छोटा सा जोड़ :) (टिप्पणियों में एक चर्चा से)) उनमें से कोई भी स्मृति में ऑब्जेक्ट नहीं हैं क्योंकि वे प्रति प्रकार वास्तविक नहीं हैं, वे एक प्रकार के मार्कर हैं - यदि आप उस गहरे में जाना चाहते हैं। लेकिन यह समझ में आता है (और यही कारण है कि MSDN ने इसे इस तरह से रखा है) IEnumerables को मेमोरी मेमोरी के रूप में सोचने के लिए जबकि IQueryables अभिव्यक्ति पेड़ों के रूप में। मुद्दा यह है कि IQueryable इंटरफ़ेस IEnumerable इंटरफ़ेस को इनहेरिट करता है ताकि यदि यह किसी क्वेरी का प्रतिनिधित्व करता है, तो उस क्वेरी के परिणामों को गणना की जा सके। एन्यूमरेशन के कारण IQueryable ऑब्जेक्ट के साथ जुड़े एक्सप्रेशन ट्री को निष्पादित किया जाता है। तो, वास्तव में, आप वास्तव में किसी भी IEnumerable सदस्य को मेमोरी में ऑब्जेक्ट के बिना कॉल नहीं कर सकते। यदि आप इसे करते हैं, तो यह वहां पहुंच जाएगा, अगर यह खाली नहीं है। IQueryables सिर्फ प्रश्न हैं, डेटा नहीं।