2012-05-09 10 views
12

उदाहरण कोड:क्या मुझे वास्तव में संग्रह पर AsQueryable() का उपयोग करने की ज़रूरत है?

List<Student> Students = new List<Student>() 
{ 
    new Student(101, "Hugo", "Garcia", new List<int>() { 91, 88, 76, 93 }), 
    new Student(102, "Rick", "Adams", new List<int>() { 70, 73, 66, 90 }), 
    new Student(103, "Michael", "Tucker", new List<int>() { 73, 80, 75, 88 }), 
    new Student(104, "Fadi", "Fakhouri", new List<int>() { 82, 75, 66, 84 }), 
    new Student(105, "Peter", "Barrows", new List<int>() { 67, 78, 70, 82 }) 
}; 

var query = from student in Students 
      where student.Marks.AsQueryable().All(m => m > 70) 
      select student; 

foreach (Student student in query) 
{ 
    Console.WriteLine("{0} {1}<br />", student.FirstName, student.LastName); 
} 

लेकिन अगर मैं

var query = from student in Students 
      where student.Marks.All(m => m > 70) 
      select student; 

यह भी काम करता है और एक ही परिणाम का उत्पादन करने के लिए क्वेरी को बदलने, तो क्या अंतर है?

+0

['AsEnumerable'] पर एक समान प्रश्न (http://stackoverflow.com/questions/3389855/am-i-misunderstanding-linq-to-sql-asenumerable) – nawfal

उत्तर

7

IQueryable की आवश्यकता है/(डेटाबेस से की तरह) दूरदराज के स्रोत से आ वस्तुओं के लिए सिफारिश की है।

स्मृति संग्रह में यह कोई उपयोग नहीं है।

AsQueryable का उपयोग तब किया जाता है जब अभिव्यक्ति वृक्ष का निर्माण किया जाता है।

मैं परिदृश्य के बारे में सोच सकता हूं जहां यह सबसे अच्छा फिट है। अपने उदाहरण में कहें कि आपको छात्र आईडी के आधार पर डेटाबेस से कुछ जानकारी की आवश्यकता है।

अब छात्र स्मृति संग्रह में है। आपको छात्र आईडी के आधार पर डेटाबेस क्वेरी को आग लगाना होगा।

var studentList = Students.Select(s => s.Id).AsQueryAble().Select(i => remoteDBProvider.GetInfo(i)); 

studentList पर आगे किसी भी आपरेशन IQueryAble इंटरफेस (क्वेरी अभिव्यक्ति) से लागू हो जाएगा, और डेटा स्रोत है, जो अंतिम क्वेरी परिणाम के रूप में किया जाना चाहिए से केवल उन रिकॉर्ड लाने कर दी जाएगी (डेटा स्रोत, वापसी के रूप में उदाहरण में remoteDBProvider.GetInfo का मान, QueryProvider का समर्थन करता है)।

+5

@ बोरीसबी। यह बिल्कुल भी सच नहीं है। [गणना योग्य। चयन करें] (http://msdn.microsoft.com/en-us/library/bb548891.aspx) स्थगित निष्पादन का भी उपयोग करता है। अंतर यह है कि क्वेरी करने योग्य लैम्बडा को अभिव्यक्ति के रूप में स्वीकार करता है। यह एक क्वेरी प्रदाता को अभिव्यक्ति का निरीक्षण करने और इसे कुछ (संभावित रूप से) अधिक कुशल में अनुवाद करने की अनुमति देता है, उदा। एक एसक्यूएल क्वेरी। किसी भी अनुमान या फ़िल्टरिंग डेटाबेस के मूल कोड का लाभ उठाते हुए, एप्लिकेशन के बजाय डेटाबेस में होगी। लेकिन इन-मेमोरी संग्रह के लिए इससे कोई फर्क नहीं पड़ता है। –

+0

@NielsvanderRest: आप सही हैं, टिप्पणी हटा दी गई है क्योंकि यह भ्रामक है (या बस असत्य)। फिर भी, 'AsQueryable' के पास अभी भी स्मृति संग्रह के लिए इसका उपयोग है, क्योंकि यह' चयन 'एक्सटेंशन विधि' अभिव्यक्ति 'स्वीकार करती है, जो आपको इसका विश्लेषण या संशोधित करने में सक्षम बनाती है। एक परिदृश्य जो मैं सोच सकता हूं, 'IQueryable' में लिपटे इन-मेमोरी संग्रह का उपयोग एक दृढ़ता-अनजान परत के लिए एक एएसटी के रूप में एक दृढ़ता-जागरूक परत के लिए एक प्रश्न भेजने के लिए है। –

2

यह करना है कि अभिव्यक्ति वृक्ष कैसे बना है। इसे देखें:

AsQueryable एक तरीका है जो क्वेरी को IQueryable के उदाहरण में परिवर्तित करने की अनुमति देता है। जब आप मौजूदा क्वेरी पर AsQueryable ऑपरेटर का उपयोग करते हैं और फ़िल्टर या एक सॉर्ट ऑर्डर निर्दिष्ट करने के रूप में आगे परिवर्तनों को लागू करते हैं, तो उन लैम्ब्डा कथन अभिव्यक्ति पेड़ में परिवर्तित होते हैं। प्रदाता के आधार पर आप का उपयोग कर रहे हैं, अभिव्यक्ति पेड़ को डोमेन विशिष्ट वाक्यविन्यास में परिवर्तित किया जाएगा और निष्पादित किया जाएगा। लिंक से SQL प्रदाता के मामले में, अभिव्यक्ति वृक्ष को SQL में परिवर्तित किया जाएगा और SQL सर्वर पर निष्पादित किया जाएगा। हालांकि यदि आप एक क्वेरी पर AsQueryable ऑपरेटर का उपयोग करते हैं जो IQueryable को लागू नहीं करता है और केवल रूपांतरणों पर लागू रूपांतरणों की तुलना में IENumerable लागू करता है, तो आप स्वचालित रूप से को IENumerable विनिर्देशन पर वापस आते हैं। इसका अर्थ यह है कि क्वेरी को AsQueryable के साथ टैग करके आप SQL से SQL और लिंक दोनों के कार्यान्वयन के लिए लाभ प्राप्त करते हैं। यदि आपकी मौजूदा क्वेरी IQueryable को कार्यान्वित करने के लिए होती है, तो क्वेरी को SQL से SQL प्रदाता, द्वारा SQL में परिवर्तित किया जाता है अन्यथा क्वेरी आईएल कोड में स्मृति में निष्पादित की जाती है।

संदर्भ here

1

आपके List<Student> के मामले में, इससे कोई फर्क नहीं पड़ता है, क्योंकि IQueryable<T> लौटने के लिए उसी विधि का उपयोग करेगा जैसे कि आपने AsQueryable() का उपयोग नहीं किया था।

कुछ तरीके IQueryable<T> पैरामीटर की अपेक्षा करते हैं।मुझे लगता है कि AsQueryable() विस्तार विधि उन परिदृश्यों के लिए अधिक उपयोगी है, जब आपको IQueryable<T> पास करने की आवश्यकता होती है लेकिन केवल IEnumerable<T> है।

स्रोत के प्रकार IQueryable<T> लागू करता है, तो AsQueryable<TElement>(IEnumerable<TElement>) रिटर्न यह सीधे:

MSDN के बारे में AsQueryable कहते हैं। अन्यथा, यह IQueryable<T> देता है जो द्वारा के में Enumerable में समकक्ष क्वेरी ऑपरेटर विधियों को कॉल करने के लिए क्वेरी निष्पादित करता है।

ताकि आपके मामले में इसका मतलब है (List<T>IQueryable<T> को लागू नहीं करता है), तुम सच में AsQueryable जरूरत नहीं है।

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