8

मैं इकाई की रूपरेखा CodeFirst जहाँ मैंआईसीओलेक्शन पर AsQueryable() वास्तव में आलसी निष्पादन करता है?

public class Person 
{ 
    public string UserName { get;set} 
    public ICollection<Blog> Blogs { get; set;} 
} 

public class Blog 
{ 
    public int id { get; set; } 
    public string Subject { get; set; } 
    public string Body { get; set; } 
} 

ठीक है के रूप में ICollection का उपयोग कर जनक बाल संबंधों का इस्तेमाल किया है उपयोग कर रहा हूँ, अब तक सब कुछ ठीक काम कर रहा है, लेकिन मेरी चिंता का विषय है, जब भी मैं एक व्यक्ति के ब्लॉग प्राप्त करना चाहते हैं, मैं इसे के रूप में

var thePerson = _context.Persons.Where(x => x.UserName = 'xxx').SingleOrDefault(); 
var theBlogs = thePerson.Blogs.OrderBy(id).Take(5); 

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

मैं जानता हूँ कि मैं अपने संदर्भ में IQueryable के रूप में ब्लॉग की घोषणा कर सकता है, ताकि मैं सीधे रूप में

var theBlogs = _context.Blogs.Where(.....) 

क्वेरी सकता है, लेकिन है कि संभव नहीं है मुझे पसंद डिजाइन के कारण के लिए, मैं के रूप में किसी भी वृत्तीय संदर्भ से बचना चाहते हैं धारावाहिक समस्या के कारण जितना संभव हो सके। इसलिए, मैंने अपने बच्चे में मूल इकाई का कोई संदर्भ नहीं दिया।

मैंने पाया कि, मैं

var theBlogs = thePerson.Blogs.AsQueryable().OrderBy(id).Take(5); 

वह मेरे लिए एक जादू की तरह लग रहा है और सच होना बहुत अच्छा लगता है के रूप में ब्लॉग पर AsQueryable() विधि कॉल कर सकते हैं। तो मेरा सवाल है। क्या यह असुविधाजनक वास्तव में आईक्लुलेक्शन को वास्तविकता में IQueryable के रूप में बनाता है और SQL सर्वर (आलसी लोडिंग) में सभी क्वेरी प्रक्रिया करता है या यह केवल एक कास्टिंग है जहां ब्लॉग पहले की तरह स्मृति में लोड होते हैं, लेकिन आईसीओलेक्शन से IQueryable में इंटरफ़ेस बदलते हैं?

+2

उत्तरार्द्ध, पूर्व में नहीं। – Enigmativity

+0

धन्यवाद - गूढ़ता, तो मेरा संदेह तब सच था। यह दुख की बात है। –

उत्तर

6

तो वास्तव में ऐसा लगता है कि आपकी नेविगेशन प्रॉपर्टी IQueryable<T>is not possible के रूप में लिख रही है।

क्या आप Blog करने के लिए एक नेविगेशन संपत्ति जोड़ रहा है कर सकता है:

public class Blog 
{ 
    public int id { get; set; } 
    public string Subject { get; set; } 
    public string Body { get; set; } 
    public virtual Person Owner { get; set; } 
} 

कि से, आप इस प्रकार क्वेरी कर सकता है तो यह स्मृति में सब कुछ लोड नहीं होगा:

var thePerson = _context.Persons.Where(x => x.UserName = 'xxx').SingleOrDefault(); 
var results = _context.Blogs.Where(z => z.Person.Name = thePerson.Name).OrderBy(id).Take(5) 

मेरा सुझाव आप SQL12 में LINQ का अनुवाद कैसे करते हैं, और वास्तव में डीबी से अनुरोध किया जाता है यह देखने के लिए LINQPad आज़माएं।

+0

आपके उत्तर के लिए बहुत बहुत धन्यवाद। ठीक है, तो इसका मतलब यह है कि, आईसीओलेक्शन IQueryable जैसे आलसी लोडर भी है और मैं सुरक्षित रूप से IQueryable के स्थान पर आईसीओलेक्शन का उपयोग कर सकता हूं जहां मैं चाहता हूं कि क्वेरी डेटाबेस में होनी चाहिए? LINQPAD के बारे में, मुझे लगता है कि एसक्यूएल अनुवाद क्या है, इसके बारे में थियोटिकल विचार देता है, लेकिन हो सकता है कि कुछ एंटिटीफ्रेमवर्क प्रोफाइलर यह देखने में बेहतर सहायता कर सके कि डेटाबेस में QUERY वास्तव में क्या भेजा जा रहा है। मेरे पास कोई एंटिटी फ्रेमवर्क प्रोफाइलर नहीं है, लेकिन अब मैं इस तरह के कुछ उत्पादों को देख रहा हूं। –

+0

बस एक और सवाल है, इसलिए यदि मेरे पिछले प्रश्न का उत्तर हाँ है, तो मुझे आईसीओलेक्शन के लिए अब AsQueryable() का उपयोग करने की आवश्यकता नहीं है, है ना? –

+1

+1 एक उपकरण की सिफारिश करने के लिए जो LINQ क्वेरीज़ को आसान बनाता है। –

2

Ladislav's answer में एक बेहतर दृष्टिकोण का वर्णन किया गया है। आपके मामले में:

var theBlogs = _context.Entry(thePerson) 
         .Collection(x => x.Blogs) 
         .Query() 
         .OrderBy(x => x.id) 
         .Take(5); 
संबंधित मुद्दे