IQueryable <T> और IEnumerable <T> में क्या अंतर है?


जवाबों:


258

सबसे पहले, इंटरफ़ेस का विस्तार करता है, इसलिए आप "सादे" के साथ कुछ भी कर सकते हैं , आप ए के साथ भी कर सकते हैं ।IQueryable<T> IEnumerable<T>IEnumerable<T>IQueryable<T>

IEnumerable<T>बस एक ऐसी GetEnumerator()विधि है जो वापस आती Enumerator<T>है जिसके लिए आप इसकी MoveNext()विधि को T के अनुक्रम से पुनरावृति कह सकते हैं ।

क्या IQueryable<T>है कि है IEnumerable<T> नहीं करता है विशेष रूप से एक में दो गुण हैं कि एक को अंक क्वेरी प्रदाता (जैसे, एसक्यूएल प्रदाता के लिए एक LINQ) और एक करने के लिए एक और एक की ओर इशारा करते क्वेरी अभिव्यक्ति का प्रतिनिधित्व IQueryable<T>एक क्रम-traversable सार वाक्य रचना पेड़ कि हो सकता है के रूप में वस्तु दिए गए क्वेरी प्रदाता द्वारा समझा जाता है (अधिकांश भाग के लिए, आप बिना किसी अपवाद के एक LINQ से इकाई प्रदाता को LINQ SQL अभिव्यक्ति नहीं दे सकते)।

अभिव्यक्ति बस वस्तु का एक निरंतर अभिव्यक्ति या क्वेरी ऑपरेटरों और ऑपरेंड के एक सम्मिलित समूह का अधिक जटिल पेड़ हो सकता है। क्वेरी प्रदाता IQueryProvider.Execute()या IQueryProvider.CreateQuery()विधियों को इसके पास दिए गए एक अभिव्यक्ति के साथ बुलाया जाता है, और फिर या तो एक क्वेरी परिणाम या किसी अन्य IQueryableको क्रमशः वापस किया जाता है।


8
क्या AsQueryable का उपयोग करने के लिए कोई लाभ है?
जॉर्डन

6
एकमात्र लाभ सुविधा है। AsQueryable()किसी क्वेरी के लिए बस एक एनम्यूएरेबल डाली जाएगी और यदि यह IQueryableइंटरफ़ेस लागू करता है तो इसे वापस कर देगा , अन्यथा यह इसे एक में लपेटता है ConstantExpression, जिसे एक लौटे EnumerableQueryऑब्जेक्ट में संदर्भित किया जाता है ।
मार्क सिडैड



@JononD लिंक मर चुका है, यहाँ का तरीका है: web.archive.org/web/20160904162931/http://www.dotnet-tricks.com/…
मज्जम

201

प्राथमिक अंतर यह है कि LINQ ऑपरेटर्स डेलिगेट्स के बजाय ऑब्जेक्ट IQueryable<T>लेते Expressionहैं, जिसका अर्थ है कि यह प्राप्त होने वाला कस्टम क्वेरी लॉजिक, उदाहरण के लिए, एक विधेय या मान चयनकर्ता, एक प्रतिनिधि के बजाय एक अभिव्यक्ति ट्री के रूप में होता है।

  • IEnumerable<T> उन सीक्वेंस के साथ काम करने के लिए बहुत अच्छा है जो इन-मेमोरी में iterated हैं, लेकिन
  • IQueryable<T> दूरस्थ डेटा स्रोत, जैसे डेटाबेस या वेब सेवा जैसी मेमोरी चीज़ों को बाहर करने की अनुमति देता है।

क्वेरी निष्पादन:

  • जहाँ एक क्वेरी का निष्पादन "प्रक्रिया में" होने वाला है , आमतौर पर क्वेरी के प्रत्येक भाग को निष्पादित करने के लिए कोड (कोड के रूप में) की आवश्यकता होती है।

  • जहां निष्पादन प्रक्रिया से बाहर हो जाएगा , क्वेरी के तर्क को डेटा में दर्शाया जाना चाहिए जैसे कि LINQ प्रदाता इसे आउट-ऑफ-मेमोरी निष्पादन के लिए उपयुक्त रूप में परिवर्तित कर सकता है - चाहे वह LDAP क्वेरी हो, SQL या जो भी हो।

ज्यादा में:

http://www.codeproject.com/KB/cs/646361/WhatHowWhere.jpg


14
मुझे आउट-ऑफ-मेमोरी ऑपरेशन का उल्लेख पसंद है। यह उपयोग में एक वास्तविक व्यावहारिक अंतर को स्पष्ट करता है।
इस्माईल स्मरनव

2
प्रतिनिधियों को IEnumerable <T> जैसे मापदंडों के रूप में लेने के बजाय, जहां विधि करता है, IQueryable <T> अभिव्यक्ति <TDelegate> मापदंडों को ले जाएगा। हम IQueryable <T> में कोड नहीं दे रहे हैं, हम विश्लेषण करने के लिए LINQ प्रदाता के लिए अभिव्यक्ति ट्री (डेटा के रूप में कोड) पास कर रहे हैं। C # 3.0 और LINQ
Lu55

आपकी छवि लिंक के साथ कुछ है, किसी कारण के लिए पोस्ट बॉडी में इसका प्रतिपादन नहीं है codeproject.com/KB/cs/646361/WhatHowWhere.jpg
jbooker

@joey फिर भी, मैं इस उत्तर में उस छवि को ठीक देखता हूं: i.stack.imgur.com/2DAqv.jpg
VonC

190

यह यूट्यूब पर एक अच्छा वीडियो है जो दर्शाता है कि ये इंटरफेस कैसे अलग हैं, एक घड़ी के लायक।

नीचे इसके लिए एक लंबा विवरणात्मक उत्तर दिया गया है।

याद रखने वाला पहला महत्वपूर्ण बिंदु IQueryableइंटरफ़ेस विरासत से है IEnumerable, इसलिए जो कुछ भी IEnumerableकर सकता है, IQueryableवह भी कर सकता है।

यहां छवि विवरण दर्ज करें

कई अंतर हैं लेकिन हम एक बड़े अंतर के बारे में चर्चा करते हैं जो सबसे बड़ा अंतर बनाता है। IEnumerableइंटरफ़ेस तब उपयोगी होता है जब आपका संग्रह LINQया इकाई ढांचे का उपयोग करके लोड किया जाता है और आप संग्रह पर फ़िल्टर लागू करना चाहते हैं।

नीचे दिए गए सरल कोड पर विचार करें जो IEnumerableइकाई ढांचे के साथ उपयोग करता है । यह एक Whereफिल्टर का उपयोग कर रहा है जिसका रिकॉर्ड EmpIdहै 2

EmpEntities ent = new EmpEntities();
IEnumerable<Employee> emp = ent.Employees; 
IEnumerable<Employee> temp = emp.Where(x => x.Empid == 2).ToList<Employee>();

यह जहाँ फ़िल्टर क्लाइंट पक्ष पर निष्पादित किया जाता है जहाँ IEnumerableकोड है। दूसरे शब्दों में, सारा डेटा डेटाबेस से प्राप्त किया जाता है और फिर क्लाइंट में इसका स्कैन किया जाता है और इसके साथ रिकॉर्ड प्राप्त होता EmpIdहै 2

यहां छवि विवरण दर्ज करें

लेकिन अब नीचे वाला कोड देखें जिसे हम बदल चुके IEnumerableहैं IQueryable। यह सर्वर साइड पर एक SQL क्वेरी बनाता है और क्लाइंट पक्ष को केवल आवश्यक डेटा भेजा जाता है।

EmpEntities ent = new EmpEntities();
IQueryable<Employee> emp = ent.Employees;
IQueryable<Employee> temp =  emp.Where(x => x.Empid == 2).ToList<Employee>();

यहां छवि विवरण दर्ज करें

तो बीच का अंतर है IQueryableऔर IEnumerableफ़िल्टर तर्क को निष्पादित करने के बारे में है। एक क्लाइंट साइड पर निष्पादित होता है और दूसरा डेटाबेस पर निष्पादित होता है।

इसलिए यदि आप केवल इन-मेमोरी डेटा संग्रह के साथ काम कर रहे हैं तो IEnumerableयह एक अच्छा विकल्प है लेकिन यदि आप डेटा संग्रह को क्वेरी करना चाहते हैं जो कि डेटाबेस से जुड़ा हुआ है `IQueryable एक बेहतर विकल्प है क्योंकि यह नेटवर्क ट्रैफ़िक को कम करता है और SQL भाषा की शक्ति का उपयोग करता है।


नमस्ते, अद्भुत स्पष्टीकरण के लिए बहुत बहुत धन्यवाद। मैं समझता हूं कि "आउट-ऑफ-मेमोरी" डेटा के लिए IQueryable बेहतर विकल्प क्यों है लेकिन मैं यह समझने के लिए संघर्ष कर रहा हूं कि IEnumerable "इन-मेमोरी" डेटा के लिए बेहतर क्यों है? मुझे अभी भी लगता है कि डेटा प्राप्त करने और फ़िल्टर लागू करने की तुलना में फ़िल्टर्ड डेटा प्राप्त करना बेहतर है।
इमाद

जब यह "इन-मेमोरी" है तो यह वास्तव में मायने नहीं रखता। डेटा पहले से ही मेमोरी पर है, जिसे फ़िल्टर किए जाने के सही समय पर कोई फर्क नहीं पड़ता।
रोनी एक्सलराड

@ उदाहरण के लिए, इकाई डेटा को परिवर्तित करके DateTimeOffset को DateTime में परिवर्तित करना संभवत: IQueryable या EntityFunctions का उपयोग करके नहीं किया जा सकता है। सबसे अच्छा तरीका है AsEnumerable () इकाई ऑब्जेक्ट के लिए, फिर डेटमॉडल को देखने वाले दृश्य में चुनें ()। यह प्रक्रिया इन-मेमोरी फ़ंक्शंस का उपयोग करती है।
जेफ ली

57

IEnumerable: IEnumerable इन-मेमोरी कलेक्शन (या स्थानीय प्रश्नों) के साथ काम करने के लिए सबसे उपयुक्त है। IEnumerable वस्तुओं के बीच नहीं चलता है, यह केवल संग्रह के लिए आगे है।

IQueryable: डेटाबेस या वेब सेवा (या दूरस्थ क्वेरी) की तरह दूरस्थ डेटा स्रोत के लिए IQueryable सबसे अच्छा सूट करता है। IQueryable एक बहुत ही शक्तिशाली विशेषता है जो विभिन्न प्रकार के दिलचस्प आस्थगित निष्पादन परिदृश्यों (जैसे पेजिंग और रचना आधारित प्रश्न) को सक्षम बनाता है।

इसलिए जब आपको इन-मेमोरी संग्रह के माध्यम से पुनरावृति करना हो, तो IEnumerable का उपयोग करें, यदि आपको डेटासेट और अन्य डेटा स्रोतों जैसे संग्रह के साथ कोई हेरफेर करने की आवश्यकता है, तो IQueryable का उपयोग करें


3
क्या IEnumerable आस्थगित निष्पादन का उपयोग नहीं करता है?
इयान वारबर्टन

3
आस्थगित निष्पादन IEnumerable और IQueryable दोनों में उपलब्ध है। इसके अलावा रोचक जानकारी यहाँ मिल सकती है: stackoverflow.com/questions/2876616/…
इग्नासियो हागोपियन

18

सरल शब्दों में अन्य प्रमुख अंतर यह है कि IEnumerable सर्वर साइड पर चुनिंदा क्वेरी को निष्पादित करता है, डेटा को इन-मेमोरी को क्लाइंट साइड पर लोड करता है और फिर डेटा को फ़िल्टर करता है जबकि IQueryable सभी फ़िल्टर के साथ सर्वर साइड पर चुनिंदा क्वेरी को निष्पादित करता है।


17

वास्तविक जीवन में, यदि आप LINM-to-SQL जैसे ORM का उपयोग कर रहे हैं

  • यदि आप एक IQueryable बनाते हैं, तो क्वेरी को sql में परिवर्तित किया जा सकता है और डेटाबेस सर्वर पर चलाया जा सकता है
  • यदि आप IEnumerable बनाते हैं, तो क्वेरी चलाने से पहले सभी पंक्तियों को ऑब्जेक्ट के रूप में मेमोरी में खींच लिया जाएगा।

दोनों मामलों में यदि आप कॉल नहीं करते हैं ToList()या ToArray()फिर क्वेरी का उपयोग होने पर हर बार निष्पादित किया जाएगा, तो, कहें, आपके पास एक है IQueryable<T>और आप इसमें से 4 सूची बॉक्स भरते हैं, फिर क्वेरी को डेटाबेस के खिलाफ 4 बार चलाया जाएगा।

यदि आप अपनी क्वेरी को सीमित करते हैं:

q.Where(x.name = "a").ToList()

तब IQueryable के साथ उत्पन्न SQL में "जहाँ नाम =" a "होगा, लेकिन IEnumerable के साथ कई और भूमिकाएँ डेटाबेस से वापस खींच ली जाएंगी, फिर x.name =" a "चेक .NET द्वारा किया जाएगा।


10

IEnumerable एक संग्रह का उल्लेख कर रहा है लेकिन IQueryable सिर्फ एक क्वेरी है और यह एक अभिव्यक्ति ट्री के अंदर उत्पन्न होगा। हम डेटाबेस से डेटा प्राप्त करने के लिए इस क्वेरी को चलाएंगे।


8

नीचे दिए गए छोटे परीक्षण आपको IQueryable<T>और के बीच अंतर के एक पहलू को समझने में मदद कर सकते हैं IEnumerable<T>। मैंने इस उत्तर को इस पोस्ट से पुन: प्रस्तुत किया है, जहाँ मैं किसी और के पोस्ट में सुधार जोड़ने की कोशिश कर रहा था

मैंने DB (DDL स्क्रिप्ट) में निम्नलिखित संरचना बनाई:

CREATE TABLE [dbo].[Employee]([PersonId] [int] NOT NULL PRIMARY KEY,[Salary] [int] NOT NULL)

यहाँ रिकॉर्ड प्रविष्टि स्क्रिप्ट (DML स्क्रिप्ट) है:

INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(1, 20)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(2, 30)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(3, 40)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(4, 50)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(5, 60)
GO

अब, मेरा लक्ष्य केवल Employeeडेटाबेस में तालिका से शीर्ष 2 रिकॉर्ड प्राप्त करना था । मैंने अपने कंसोल एप्लिकेशन में ADO.NET इकाई डेटा मॉडल आइटम को Employeeअपने डेटाबेस में तालिका में जोड़ा और LINQ क्वेरी लिखना शुरू कर दिया।

IQueryable मार्ग के लिए कोड :

using (var efContext = new EfTestEntities())
{
    IQueryable<int> employees = from e in efContext.Employees  select e.Salary;
    employees = employees.Take(2);

    foreach (var item in employees)
    {
        Console.WriteLine(item);
    }
}

जब मैंने इस प्रोग्राम को चलाना शुरू किया, तो मैंने अपने SQL सर्वर इंस्टेंस पर SQL क्वेरी प्रोफाइलर का एक सत्र भी शुरू किया था और यहाँ प्रस्तुत है:

  1. कुल प्रश्नों की संख्या निकाल दी गई: 1
  2. क्वेरी पाठ: SELECT TOP (2) [c].[Salary] AS [Salary] FROM [dbo].[Employee] AS [c]

यह सिर्फ इतना IQueryableहै कि लागू करने के लिए पर्याप्त स्मार्ट हैTop (2) डेटाबेस सर्वर साइड पर क्लॉज इसलिए यह तार पर 5 में से केवल 2 रिकॉर्ड लाता है। क्लाइंट कंप्यूटर साइड पर किसी भी इन-मेमोरी फ़िल्टरिंग की आवश्यकता नहीं है।

IEnumerable मार्ग के लिए कोड :

using (var efContext = new EfTestEntities())
{
    IEnumerable<int> employees = from e in efContext.Employees  select e.Salary;
    employees = employees.Take(2);

    foreach (var item in employees)
    {
        Console.WriteLine(item);
    }
}

इस मामले में निष्पादन का सारांश:

  1. कुल प्रश्नों की संख्या निकाल दी गई: 1
  2. SQL प्रोफाइलर में क्वेरी पाठ कैप्चर किया गया: SELECT [Extent1].[Salary] AS [Salary] FROM [dbo].[Employee] AS [Extent1]

अब बात टेबल IEnumerableमें मौजूद सभी 5 रिकॉर्ड्स की है Salaryऔर फिर टॉप 2 रिकॉर्ड पाने के लिए क्लाइंट कंप्यूटर पर इन-मेमोरी फिल्टरिंग की। तो अधिक डेटा (इस मामले में 3 अतिरिक्त रिकॉर्ड) तार पर अनावश्यक रूप से स्थानांतरित हो गए।


7

यहाँ मैंने इसी तरह की पोस्ट (इस विषय पर) पर लिखा है। (और नहीं, मैं आमतौर पर खुद को उद्धृत नहीं करता हूं, लेकिन ये बहुत अच्छे लेख हैं।)

"यह लेख सहायक है: IQQ-I-SQL में IQueryable बनाम IEnumerable

उस लेख का हवाला देते हुए, 'MSDN प्रलेखन के अनुसार, IQueryable पर किए गए कॉल इसके बजाय आंतरिक अभिव्यक्ति ट्री के निर्माण से संचालित होते हैं। "ये विधियाँ जो IQueryable का विस्तार करती हैं (T की) सीधे कोई क्वेरी नहीं करती हैं। इसके बजाय, उनकी कार्यक्षमता अभिव्यक्ति ऑब्जेक्ट बनाने के लिए है, जो एक अभिव्यक्ति ट्री है जो संचयी क्वेरी का प्रतिनिधित्व करता है।" '

अभिव्यक्ति पेड़ C # और .NET प्लेटफ़ॉर्म पर एक बहुत महत्वपूर्ण निर्माण हैं। (वे सामान्य रूप से महत्वपूर्ण हैं, लेकिन C # उन्हें बहुत उपयोगी बनाता है।) अंतर को बेहतर ढंग से समझने के लिए, मैं यहां आधिकारिक C # 5.0 विनिर्देशन में अभिव्यक्तियों और कथनों के बीच के अंतर के बारे में पढ़ने की सलाह देता हूं उन्नत सैद्धांतिक अवधारणाओं के लिए जो लैम्ब्डा कैलकुलस में शाखा करते हैं, अभिव्यक्ति प्रथम श्रेणी की वस्तुओं के रूप में तरीकों के लिए समर्थन को सक्षम करती हैं। IQueryable और IEnumerable के बीच अंतर इस बिंदु के आसपास केंद्रित है। IQueryable अभिव्यक्ति पेड़ बनाता है जबकि IEnumerable कम से कम नहीं है, हम में से उन लोगों के लिए सामान्य शब्दों में नहीं है जो Microsoft की गुप्त प्रयोगशालाओं में काम नहीं करते हैं।

यहां एक और बहुत उपयोगी लेख है जो एक धक्का बनाम पुल के परिप्रेक्ष्य से मतभेदों का विवरण देता है। ("धक्का" बनाम "पुल", मैं डेटा प्रवाह की दिशा का उल्लेख कर रहा हूं। NET और C # के लिए प्रतिक्रियाशील प्रोग्रामिंग तकनीक

यहाँ एक बहुत अच्छा लेख है जो स्टेटमेंट लैम्ब्डा और एक्सप्रेशन लैम्ब्डा के बीच के अंतरों का विवरण देता है और अभिव्यक्ति की अवधारणाओं पर अधिक गहराई से चर्चा करता है: सी # डेलिगेट्स, एक्सप्रेशन ट्री, और लैम्ब्डा स्टेटमेंट्स बनाम लैम्ब्डा एक्सप्रेशंस पर फिर से विचार करना। । "


6

हम डेटाबेस से पुनर्प्राप्त डेटा का उपयोग IEnumerableऔर IQueryableहेरफेर करते हैं। IQueryableइनहेरिट करता है IEnumerable, इसलिए IQueryableइसमें सभी IEnumerableविशेषताएं हैं। के बीच बड़ा अंतर IQueryableहै और IEnumerableवह यह है कि IQueryableफिल्टर के साथ निष्पादित क्वेरी जबकि IEnumerableकार्यान्वित क्वेरी पहले और फिर इसे शर्तों के आधार पर डेटा फिल्टर।

नीचे और अधिक विस्तृत भेदभाव खोजें:

IEnumerable

  1. IEnumerableSystem.Collectionsनामस्थान में मौजूद है
  2. IEnumerable सर्वर साइड पर एक चुनिंदा क्वेरी निष्पादित करें, क्लाइंट-साइड पर डेटा इन-मेमोरी लोड करें और फिर डेटा फ़िल्टर करें
  3. IEnumerable सूची, सरणी जैसे इन-मेमोरी संग्रह के डेटा को क्वेरी करने के लिए उपयुक्त है
  4. IEnumerable LINQ to Object और LINQ to XML क्वेरीज़ के लिए फायदेमंद है

IQueryable

  1. IQueryableSystem.Linqनामस्थान में मौजूद है
  2. IQueryable सभी फ़िल्टर के साथ सर्वर-साइड पर 'चयन क्वेरी' निष्पादित करता है
  3. IQueryable आउट-मेमोरी (जैसे दूरस्थ डेटाबेस, सेवा) संग्रह से डेटा को क्वेरी करने के लिए उपयुक्त है
  4. IQueryable LINQ to SQL क्वेरी के लिए फायदेमंद है

तो IEnumerableआम तौर पर इन-मेमोरी संग्रह से निपटने के लिए उपयोग किया जाता है, जबकि, IQueryableआमतौर पर संग्रह में हेरफेर करने के लिए उपयोग किया जाता है।


3

IEnumerable और IQueryable दोनों का उपयोग डेटा के संग्रह को रखने के लिए किया जाता है और डेटा के संग्रह पर उदाहरण के लिए डेटा हेरफेर ऑपरेशन निष्पादित करता है। यहां आप उदाहरण के साथ तुलना में सबसे अच्छा अंतर पा सकते हैं। http://www.gurujipoint.com/2017/05/difference-between-ienumerable-and.html यहां छवि विवरण दर्ज करें


2

आईक्यूएबल IEnumerable की तुलना में तेज़ है यदि हम डेटाबेस से भारी मात्रा में डेटा के साथ काम कर रहे हैं क्योंकि, IQueryable को केवल डेटाबेस से आवश्यक डेटा प्राप्त होता है, जहां IEnumerable डेटाबेस से आवश्यकता की परवाह किए बिना सभी डेटा प्राप्त करता है


0

ienumerable: जब हम inprocess मैमोरी से निपटना चाहते हैं, यानी बिना डाटाकॉन्नेक्शन के iqueryable: जब sql सर्वर से निपटने के लिए, यानी डेटा कनेक्शन के साथ ilist: ऑपर जैसे ऐड ऑब्जेक्ट, डिलीट ऑब्जेक्ट आदि

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.