AsQueryable () का उद्देश्य क्या है?


107

का उद्देश्य है AsQueryable()सिर्फ इसलिए आप के चारों ओर एक पारित कर सकते हैं IEnumerableतरीकों कि उम्मीद कर सकते हैं करने के लिए IQueryable, या कोई प्रतिनिधित्व करने के लिए एक उपयोगी कारण है IEnumerableके रूप में IQueryable? उदाहरण के लिए, क्या यह इस तरह के मामलों के लिए होना चाहिए:

IEnumerable<Order> orders = orderRepo.GetAll();

// I don't want to create another method that works on IEnumerable,
// so I convert it here.
CountOrders(orders.AsQueryable());

public static int CountOrders(IQueryable<Order> ordersQuery)
{
    return ordersQuery.Count();
}

या क्या यह वास्तव में कुछ अलग करता है:

IEnumerable<Order> orders = orderRepo.GetAll();
IQueryable<Order> ordersQuery = orders.AsQueryable();

IEnumerable<Order> filteredOrders = orders.Where(o => o.CustomerId == 3);
IQueryable<Order> filteredOrdersQuery = ordersQuery.Where(o => o.CustomerId == 3);

// Are these executed in a different way?
int result1 = filteredOrders.Count();
int result2 = filteredOrdersQuery.Count();

क्या IQueryableइन विस्तार विधियों के संस्करणों में एक एक्सप्रेशन का निर्माण होता है जो एक ही बार निष्पादित होने के बाद समाप्त होता है? मेरा मुख्य सवाल यह है कि, उपयोग करने के लिए वास्तविक उपयोग का मामला क्या है AsQueryable?

जवाबों:


65

कुछ मुख्य उपयोग हैं।

  1. जैसा कि अन्य उत्तरों में उल्लेख किया गया है, आप इन-मेमोरी डेटा स्रोत का उपयोग करके एक क्वेरी करने योग्य डेटा स्रोत को मॉक करने के लिए इसका उपयोग कर सकते हैं ताकि आप अधिक आसानी से परीक्षण विधियों का उपयोग कर सकें जो अंततः गैर-एन्यूमरेबल आधारित पर उपयोग किए जाएंगे IQueryable

  2. आप संग्रह में हेरफेर करने के लिए सहायक तरीके लिख सकते हैं जो मेमोरी इनविंडेंस या बाहरी डेटा स्रोतों पर लागू हो सकते हैं। यदि आप IQueryableपूरी तरह से उपयोग करने के लिए अपनी सहायता विधियाँ लिखते हैं, तो आप AsQueryableइनका उपयोग करने के लिए सभी प्रगणकों पर उपयोग कर सकते हैं यह आपको बहुत सामान्यीकृत सहायक विधियों के दो अलग-अलग संस्करणों को लिखने से बचने की अनुमति देता है।

  3. यह आपको IQueryableकुछ अधिक व्युत्पन्न प्रकारों के बजाय एक क्वेरी के संकलन समय प्रकार को बदलने की अनुमति देता है । प्रभाव में; आप एक पर उसका प्रयोग करेंगे IQueryableएक ही समय पर है कि आप उपयोग करना चाहते हैं AsEnumerableएक पर IEnumerable। आपके पास एक ऐसी वस्तु हो सकती है जो लागू होती है, IQueryableलेकिन उसके पास एक उदाहरण Selectविधि भी है । यदि ऐसा होता, और आप LINQ Selectविधि का उपयोग करना चाहते थे , तो आपको ऑब्जेक्ट के संकलन समय प्रकार को बदलना होगा IQueryable। आप इसे केवल कास्ट कर सकते हैं, लेकिन एक AsQueryableविधि होने से आप टाइप इंट्रेंस का लाभ उठा सकते हैं। यह केवल अधिक सुविधाजनक है यदि सामान्य तर्क सूची जटिल है, और यह वास्तव में आवश्यक है यदि कोई भी सामान्य तर्क अनाम प्रकार हैं।


पुनरुद्धार के लिए धन्यवाद। इसे उत्तर के रूप में चिह्नित करना क्योंकि यह सबसे पूर्ण है।
Ocelot20

5
यह देखते हुए कि IQueryable<T>से व्युत्पन्न IEnumerable<T>आप बताएं कि आपको "गैर गणनीय आधारित IQueryable" द्वारा क्या मतलब है कृपया कर सकते हैं?
दाई

2
@Dai यह जिक्र है IQueryableकि केवल एक लिपटे से अधिक है IEnumerable, और यह वास्तव में एक की अतिरिक्त क्षमताओं का लाभ उठाता है IQueryable
3

# 1 बिल्कुल वही है जो मैं इसके लिए चाह रहा था। सत्यापित करने के लिए धन्यवाद।
one.beat.consumer

12

AsQueryable के लिए मेरे पास सबसे वैध मामला इकाई परीक्षण है। कहो कि मेरे पास निम्नलिखित कुछ उदाहरण हैं

public interface IWidgetRepository
{
   IQueryable<Widget> Retrieve();
} 

public class WidgetController
{
   public IWidgetRepository WidgetRepository {get; set;}


   public IQueryable<Widget> Get()
   {
      return WidgetRepository.Retrieve();
   }
}

और मैं यह सुनिश्चित करने के लिए एक इकाई परीक्षण लिखना चाहता हूं कि नियंत्रक रिपॉजिटरी से वापस किए गए परिणामों को वापस करता है। यह कुछ इस तरह दिखेगा:

[TestMethod]
public void VerifyRepositoryOutputIsReturned()
{    
    var widget1 = new Widget();
    var widget2 = new Widget();
    var listOfWidgets = new List<Widget>() {widget1, widget2};
    var widgetRepository = new Mock<IWidgetRepository>();
    widgetRepository.Setup(r => r.Retrieve())
      .Returns(listOfWidgets.AsQueryable());
    var controller = new WidgetController();
    controller.WidgetRepository = widgetRepository.Object;

    var results = controller.Get();

    Assert.AreEqual(2, results.Count());
    Assert.IsTrue(results.Contains(widget1));
    Assert.IsTrue(results.Contains(widget2));
}

जहां वास्तव में, सभी AsQueryable () विधि मुझे एक मॉक सेट करते समय संकलक को संतुष्ट करने की अनुमति देती है।

मैं जहां यह आवेदन कोड में प्रयोग किया जाता है, हालांकि दिलचस्पी होगी।


11

जैसा कि sanjuro ने कहा, AsQueryable () का उद्देश्य Asqable को Linq To ऑब्जेक्ट्स और Linq To SQL में उपयोग करने के बारे में बताया गया है । विशेष रूप से, लेख में कहा गया है,

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


6

इस लेख में AsQueryable () का उद्देश्य बहुत समझाया गया है। AsQueryable with Linq To Objects and Linq To SQL

MSDN Queryable.AsQueryable विधि के रिमार्क्स अनुभाग से:

यदि स्रोत का प्रकार IQueryable लागू करता है, तो AsQueryable (IEnumerable) इसे सीधे लौटाता है। अन्यथा, यह एक IQueryable को लौटाता है, जो क्वेरी योग्य लोगों के बजाय Enumerable में समकक्ष क्वेरी ऑपरेटर विधियों को कॉल करके प्रश्नों को निष्पादित करता है।

यह वही है जो उपरोक्त लेख में उल्लिखित और उपयोग किया गया है। आपके उदाहरण में, यह इस बात पर निर्भर करता है कि क्या ऑर्डर है। पुन: गेट। सभी लौटकर, IEnumerable या IQueryable (Sql को Linq)। यदि यह IQueryable देता है, तो गणना () विधि डेटाबेस पर निष्पादित की जाएगी अन्यथा इसे मेमोरी में निष्पादित किया जाएगा। संदर्भित लेख में उदाहरण को ध्यान से देखें।


3

इंटरफ़ेस IQueryableउद्धरण प्रलेखन:

IQueryable इंटरफ़ेस क्वेरी प्रदाताओं द्वारा कार्यान्वयन के लिए अभिप्रेत है।

तो किसी ऐसे व्यक्ति के लिए जो अपने डेटास्ट्रेक्चर को .NET में क्वेरी करने योग्य बनाता है, वह डेटास्ट्रक्चर जो आवश्यक नहीं है, एन्यूमरेट किया जा सकता है या उसके पास वैध एन्यूमरेटर हो सकता है

IEnumeratorइसके बजाय डेटा की पुनरावृत्ति और प्रसंस्करण स्ट्रीम के लिए एक इंटरफ़ेस है ।


क्या आप इस पर पुनर्विचार करने का मन बनायेंगे: "उस डेटास्ट्रक्चर को जिसे आवश्यक नहीं माना जा सकता है या जिसके पास वैध एन्यूमरेटर है"। मैं IQueryableऔर के बीच का अंतर समझता हूं IEnumerable, लेकिन मैं AsQueryableविस्तार विधि के लिए उपयोग के मामले को नहीं समझता । मैं उस वाक्य पर थोड़ा तिकड़मबाज़ी कर रहा हूँ, जो मुझे संदेह है कि मुझे वह उत्तर मिल सकता है जिसकी मुझे तलाश है (upvotes के आधार पर)।
Ocelot20

@ Ocelot20: इसका अर्थ है कि प्रदाता द्वारा प्रस्तुत किए गए टोपी डेटास्ट्रक्चर जो कि IQueryable को लागू करता है, एक गणना क्षमता प्रदान नहीं कर सकता है । यह प्रदाता पर निर्भर है। डॉक्यूमेंट को उद्धृत करते हुए: "क्वेरीज, जो एग्ज़िक्यूट विधि कहलाती हैं, पर अमूल्य परिणाम वापस नहीं करती हैं।"
तिगरान

शायद मैं कुछ स्पष्ट याद कर रहा हूँ, लेकिन मैं अभी भी जवाब देने के लिए नहीं दिख रहा है "मैं क्यों उपयोग करने की आवश्यकता होगी AsQueryable()?" यदि मैं एक IEnumerable (कुछ पहले से ही एक संधारित्र क्षमता प्रदान करने में सक्षम) के साथ शुरू कर रहा हूं , तो मुझे IQueryableएक्सटेंशन विधि का उपयोग करने के लिए कन्वर्ट करने की आवश्यकता क्यों होगी AsQueryable()? शायद यह बताने के लिए एक छोटा कोड उदाहरण कि यह कहाँ काम आएगा? मुझे आपके स्पष्टीकरण में कुछ याद आ रहा है। आपके समय के लिए धन्यवाद।
Ocelot20

@ Ocelot20: क्वेरी प्रदाता लिखने के लिए मुझे वास्तव में अंतर दिखाने की आवश्यकता है। आपको पता है कि हमारे पास है linq to sql, linq to xmlऔर इसलिए .. यदि आप linqड्राइवर को लिखना चाहते हैं जो आपके डेटा स्ट्रक्यूट्रेस ( linq to your data) को लक्षित करता है , तो आपके एपीआई के उपयोगकर्ताओं को आपके डेटा संरचनाओं के linqखिलाफ क्वेरी चलाने की संभावना होगी , आपको चुनना होगाIQueryable
टाइगरान

2
आप के बीच के अंतर को स्पष्ट करने लगते हैं IQueryableऔर IEnumerable। मुझे अंतर पता है, और यह वह नहीं है जो मैं पूछ रहा हूं। मैं पूछ रहा हूं कि कोई व्यक्ति कुछ ऐसा क्यों लेना चाहता है जो लागू करता है IEnumerable, और इसे एक्सटेंशन विधि IQueryableका उपयोग करके परिवर्तित करें AsQueryable। क्या आप इसका जवाब दे रहे हैं? मैं अभी भी नहीं बता सकता ..
Ocelot20
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.