2013-05-08 9 views
5

क्वेरी करने मैं यहाँ सेकैसे IQueryable <T> वापस जाने के लिए आगे

https://github.com/TroyGoode/PagedList

जो इस प्रयोग नमूना MyProductDataSource.FindAllProducts की

var products = MyProductDataSource.FindAllProducts(); //returns IQueryable<Product> representing an unknown number of products. a thousand maybe? 

     var pageNumber = page ?? 1; // if no page was specified in the querystring, default to the first page (1) 
     var onePageOfProducts = products.ToPagedList(pageNumber, 25); // will only contain 25 products max because of the pageSize 

ठेठ implmentations है PagedList.Mvc पुस्तकालय कोशिश कर रहा हूँ के लिए ();

public IQuerable<T> MyProductDataSource.FindAllProducts() 
{ 
    using (var ctx = new MyCtx()) 
    { 
     return ctx.MyList().Where(....); 
    } 
} 

जो निश्चित रूप से InvalidOperationException() है और DBContext पहले से ही संदेश निपटान किया जाता है

कैसे IQueryable जो मुद्दों के बिना यहां इस्तेमाल किया जा सकता वापस जाने के लिए पर सर्वोत्तम प्रथाओं के लिए खोज रहे की तर्ज पर कर रहे हैं?

using (var ctx = new MyCtx()) 
{ 
    var products = MyProductDataSource.FindAllProducts(ctx); 

    var pageNumber = page ?? 1; 
    var onePageOfProducts = products.ToPagedList(pageNumber, 25); 
} 
+0

यह एक सामान्य कार्यान्वयन नहीं है। आम तौर पर आप एक रेपॉजिटरी क्लास में एक संदर्भ इंजेक्ट करते हैं जिसका अर्थ है कि आप विधि स्तर पर निपटान नहीं करते हैं। –

+0

@WiktorZychla मैं असहमत हूं। दोनों उपयोगी कार्यान्वयन हैं। जब विधि को स्थानीय रूप से संदर्भ को पार करना संभव हो, तो यह करने के लिए एक स्वीकार्य बात है, लेकिन जब क्वेरी की पीढ़ी उस विधि के दायरे से बाहर हो जाती है जो कि कोई विकल्प नहीं है, ऐसे मामलों में आपको संदर्भ के दायरे को समायोजित करने की आवश्यकता है कि, जहां भी यह है, यह उस क्वेरी के जीवनकाल को शामिल करता है। प्रोग्रामर को यह समझने में सक्षम होना चाहिए कि किसी भी दिए गए प्रश्न का जीवनकाल क्या है और इस संदर्भ को दायरा दें कि यह उसी "स्तर" पर है, और नहीं, कम नहीं। – Servy

+0

@ सर्वी: सच है लेकिन ज्यादातर मामलों में आपका संदर्भ जीवनकाल "प्रति-http-context" है। ध्यान दें कि वह एएसपीनेट के साथ सवाल टैग करता है।आप जो कहते हैं वह एक सामान्य सिद्धांत का एक टुकड़ा है, उसे अपने विशिष्ट, एएसपीनेट परिदृश्य के लिए एक सटीक मार्गदर्शन की आवश्यकता है। –

उत्तर

3

आप अपने डेटा संदर्भ के दायरे "ऊपर ले जाएँ" करने की जरूरत है आईओसी कंटेनर का उपयोग करके प्रति HTTP अनुरोध के रूप में डीबीकॉन्टेक्स्ट, अधिकांश आईओसी कंटेनर HttpRequest जीवनकाल का समर्थन करते हैं।

तो आप डीबीकॉन्टेक्स्ट के दायरे का लाभ उठा सकते हैं जो आपको ऊपरी परत पर IQueryable का उपयोग करने की अनुमति देता है।

अधिक जानकारी जो दो आईओसी कंटेनर मुझे पसंद है: autofac और Ninject

कैसे autofachere

में MVC का समर्थन करता है या कैसे NInjecthere

यदि आप आईओसी कंटेनर पर नए हैं में MVC का समर्थन करता है, तो आप सुझाव है कि आप एक मार्टिन फूल से dependency injection की मूल अवधारणा को देखने के लिए ले जाना चाहिए। फिर आपके द्वारा चुने गए आईओसी कंटेनर में से एक के साथ आगे बढ़ें।

लेकिन, आपको IQueryable का उपयोग करने के तरीके पर बहुत सावधान रहने की आवश्यकता है और आपको कौन सी परत का समर्थन करना बंद कर देना चाहिए। यदि नहीं, तो पीछे की शैतान, आलसी लोडिंग से आलसी लोडिंग प्रदर्शन को धीमा कर देगी। मेरे नियम में से एक दृश्य पर IQueryable का समर्थन नहीं करता है।

+0

एक विकल्प को प्रत्येक स्रोत की बजाय डेटा स्रोत में संदर्भ इंजेक्ट करना होगा। –

+0

@WiktorZychla बिंदु यह है कि संदर्भ के जीवनकाल को क्वेरी के जीवनकाल से अधिक बढ़ाने की आवश्यकता है, आपको यह जानने के लिए कितना अधिक जाना है कि निश्चित रूप से क्वेरी के आधार पर भिन्नता हो सकती है। इसे उस वस्तु के दायरे में होना आवश्यक हो सकता है, या ऐसा नहीं हो सकता है। – Servy

+0

मुझे लगता है कि IQueryable होना चाहिए –

4

अच्छा अभ्यास के जीवनकाल रखने के लिए है:

public IQueryable<T> MyProductDataSource.FindAllProducts(MyCtx context) 
{ 
    return context.MyList().Where(....); 
} 

फिर बड़े दायरे में प्रसंग बना:

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