2010-07-18 7 views
14

तो मैं IQueryable<T> को समझने की कोशिश कर रहा हूं। एक ट्यूटोरियल जो मैं पढ़ रहा हूं उसका उपयोग करने का सुझाव देता है लेकिन वास्तव में क्यों नहीं। कोड LINQ से SQL का उपयोग करके कुछ मान देता है। मैंने अतीत में यह कई बार किया है, लेकिन IQueryable<T>मुझे समझ में समस्याएं आ रही हैं IQueryable <T>

का उपयोग क्यों नहीं करें मेरे कार्यों के साथ इसका उपयोग क्यों करें जो 1 से अधिक मूल्य लौटाते हैं?

public IQueryable<Items> GetItems() 
    { 
     return from item in db.Items 
       where item.IsActive == true 
       orderby item.ItemNumber 
       select item; 
    } 
+2

महान प्रश्न में मदद करता है। आपने मुझे शोध के घंटे बचाए। – KyleM

उत्तर

12

IQueryable सर्वर पर मूल्यांकन करने के बिना एक अभिव्यक्ति पेड़ के रूप में क्वेरी का प्रतिनिधित्व करता है:

यहाँ मेरी कोड है। यह वास्तव में SQL उत्पन्न करने से पहले आगे प्रसंस्करण निर्दिष्ट करने देता है।

ऊपर मामले में, यह मतलब है कि आप GetItems() कॉल के परिणाम के साथ सामान कर सकते हैं, और मूल क्वेरी और किसी एक क्वेरी के रूप में भेजा अतिरिक्त सामान है:

var recentItems = from item in GetItems() 
        where item.Timestamp > somedate 
        select item; 

foreach (var item in recentItems) 
{ 
    // Do something with an active recent item. 
} 

कुछ भी नहीं भेज दिया जाता है सर्वर तक जब तक हम फ़ोरैच लूप में परिणाम का उपभोग करने का प्रयास नहीं करते हैं। उस बिंदु पर, LINQ-to-SQL प्रदाता संपूर्ण अभिव्यक्ति का आकलन करता है, जिसमें GetItems() के अंदर उत्पन्न बिट्स और बाद में निर्दिष्ट बिट्स शामिल हैं, और एक एकल SQL कथन उत्सर्जित करता है जो सक्रिय और हालिया दोनों आइटमों का चयन करता है।

तकनीकीता को स्पष्ट करने के लिए, IQueryable<T> एक IEnumerable<T> है, और जब आप GetEnumerator() विधि को आमंत्रित करने का प्रयास करते हैं तो इसका प्रदाता अंतिम SQL की गणना करता है। आप या तो इसे कॉल करके स्पष्ट रूप से कर सकते हैं, या foreach कथन में इसका उपयोग करके स्पष्ट रूप से ऐसा कर सकते हैं। साथ ही, ToArray() जैसे विस्तार विधियां आंतरिक रूप से इनमें से एक कार्य करेंगी, इस प्रकार एक ही प्रभाव उत्पन्न करेंगी।

+0

तो IENumerable <> - यह केवल 'foreach' या '.ToArray()' का मूल्यांकन किया जाता है। तो IQueryable <> IENumerable <> के लिए अलग क्यों है? – Enigmativity

+0

एक IQueryable * एक आईनेमरेबल है, और वे दोनों देर से संग्रहित संग्रह प्रदान कर सकते हैं। लेकिन, L2S में IQuerable का बिंदु SQL निष्पादन में देरी हो रही है। IQueryable के साथ, आप क्वेरी तत्वों को जोड़ना जारी रख सकते हैं, जैसे।() शर्तों को जब तक आप अंततः गणना करना शुरू करते हैं तब तक। उस बिंदु पर, IQueryable अंत में SQL क्वेरी निष्पादित करता है और आपके लिए गणना करने के लिए एक संग्रह भरता है। यदि आप सुनिश्चित हैं कि आप अपनी क्वेरी के साथ समाप्त हो गए हैं और आपकी विधि को कॉल करने के लिए कुछ भी शर्तों को जोड़ने की आवश्यकता नहीं है, तो आप बस कॉल करने का निर्णय ले सकते हैं। टोस्टिस्ट() और एक IQuerable लौटने के लिए w/o किया जाना चाहिए। – mattmc3

+0

'IQueryable ' 'IENumerable ' इंटरफ़ेस लागू करता है, इसलिए 'IQueryable' को 'IENumerable' के रूप में उपयोग किया जा सकता है। बड़ा अंतर यह है कि IQueryable ऑपरेशन (संकलित कोड) के बजाए ऑपरेशन की परिभाषा है। यह LINQ से SQL प्रदाता को इसका विश्लेषण करने और इसे SQL में बदलने की अनुमति देता है। यह सामान्य संकलित कोड के साथ (लगभग) असंभव होगा। – Steven

5

एक IQueryable (इससे पहले कि यह समझा जाता है) परिणाम न ही परिणाम हैं, लेकिन तर्क उन परिणामों को वापस करने के लिए उपयोग किया जाता है।

LINQ2SQL उदाहरण का उपयोग करने के लिए ... कल्पना करें कि आप ग्राहकों का एक IQueryable वापस कर सकते हैं। हुड कि ग्राहकों की एक सूची नहीं होगा के तहत (जब तक आप ToList() यह), लेकिन वास्तव में तो जैसे एक एसक्यूएल क्वेरी होगा:

SELECT * FROM [Clients] 

अब इस काम है क्योंकि हम डेटाबेस अभी तक हिट नहीं किया है!

var clients = GetClients().Where(c => c.Name == "Bob"); 

अब IQueriable हुड के नीचे इस तरह दिखता है:

SELECT * FROM [Clients] WHERE Name = 'Bob'. 

अब जब तो कहते हैं कि जब कि IQueriable वापस आता है हम हम कर सकते हैं ग्राहक "बॉब" कहा जाता है के लिए नीचे को परिष्कृत करना चाहते हैं मैं क्लाइंट करता हूं। टोलिस्ट(), वह क्वेरी चलती है, डेटाबेस हिट हो जाता है, और मेरे पास बॉब नामक क्लाइंट्स की एक सूची है जो सभी क्लाइंटों को चुनने के बिना मेमोरी में ट्रैवल करता है, या 2 अलग डेटाबेस हिट करता है।

इसके पीछे कोशिश करते हैं और जब अपने DataContext क्षेत्र से बाहर गिरा दिया बच्चे तत्वों को पाने में आप काट का एक उदाहरण के लिए (उदाहरण के लिए: एक बयान का उपयोग कर के अंदर अपने चयन को चलाने)। यह वह जगह है जहां LINQ2SQL में लोड विकल्प आसान होते हैं।

आशा है कि

+0

तो IENumerable <> - यह केवल मूल्यांकन किया जाता है '.सूची() 'कहा जाता है। तो IQueryable <> IENumerable <> के लिए अलग क्यों है? – Enigmativity

+0

IQueryable समझा जाने से पहले आपका डेटा अभी भी एक अभिव्यक्ति वृक्ष है ... LINQ2SQL के उदाहरण में आप अपने चयन * ग्राहकों से एक आईनेमरेबल के रूप में नहीं हो सकते क्योंकि यह एक अभिव्यक्ति है और इसमें कोई गणना योग्य मान नहीं है जब तक कि यह स्वयं चलाने की क्वेरी न हो। हालांकि यह एक अनगिनत IQueryable बनी हुई है, आप अभिव्यक्ति वृक्ष को बढ़ाने वाले खंड जोड़ सकते हैं। – jdoig

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