2013-04-26 7 views
5

निष्पादित करता है मैं दृढ़ता से टाइप किए गए वर्गों के लिए LINQ से SQL परिणामों का प्रक्षेपण कर रहा हूं: माता-पिता और बच्चे। इन दो प्रश्नों के प्रदर्शन के बीच अंतर बड़ा है:एक से कई प्रोजेक्ट LINQ क्वेरी बार-बार

धीरे क्वेरी - DataContext से प्रवेश करने से पता चलता है कि डाटाबेस के लिए एक अलग कॉल हर माता-पिता के लिए बनाया जा रहा है

var q = from p in parenttable 
     select new Parent() 
     { 
      id = p.id, 
      Children = (from c in childtable 
         where c.parentid = p.id 
         select c).ToList() 
     } 
return q.ToList() //SLOW 

फास्ट क्वेरी - DataContext शो से प्रवेश करने एक एकल डाटाबेस हिट क्वेरी कि सभी आवश्यक डेटा

var q = from p in parenttable 
     select new Parent() 
     { 
      id = p.id, 
      Children = from c in childtable 
         where c.parentid = p.id 
         select c 
     } 
return q.ToList() //FAST 

मैं दूसरे उदाहरण के एकल क्वेरी शैली का उपयोग करने के लिए मजबूर LINQ, लेकिन उनके बच्चों के साथ माता पिता वर्गों को भरने के लिए चाहते हैं देता है सीधे वस्तुओं। अन्यथा, बच्चों की संपत्ति IQuerierable<Child> है जिसे चाइल्ड ऑब्जेक्ट का पर्दाफाश करने के लिए पूछताछ की जानी चाहिए।

संदर्भित प्रश्न मेरी स्थिति को हल करने के लिए प्रकट नहीं होते हैं। db.LoadOptions का उपयोग कर काम नहीं करता है। शायद इसे डेटाकॉन्टेक्स्ट के साथ पंजीकृत एक TENTITY होने की आवश्यकता है।

DataLoadOptions options = new DataLoadOptions(); 
    options.LoadWith<Parent>(p => p.Children); 
    db.LoadOptions = options; 

कृपया ध्यान दें: जनक एवं बाल सरल प्रकार, नहीं Table<TEntity> प्रकार हैं। और माता-पिता और बच्चे के बीच कोई प्रासंगिक संबंध नहीं है। subqueries विज्ञापन हैं।

जारी करने की क्रक्स: 2 LINQ उदाहरण में मैं IQueriable बयान को लागू करने और ToList() फ़ंक्शन को कॉल नहीं करते हैं और किसी कारण से LINQ जानता है कि कैसे एक ही क्वेरी कि सभी आवश्यक डेटा प्राप्त कर सकते हैं उत्पन्न करने के लिए। मैं पहली क्वेरी में पूरा किए गए वास्तविक डेटा के साथ अपने विज्ञापन-प्रसार प्रक्षेपण को कैसे पॉप्युलेट करूं? इसके अलावा, अगर कोई मेरे प्रश्न को बेहतर-वाक्यांश में मदद कर सकता है, तो मैं इसकी सराहना करता हूं।

+0

'चाइल्ड' एक "सरल प्रकार" कैसे हो सकता है? यह एक मैप प्रकार होना चाहिए। और 'parenttable'' table' है या पिछले linq क्वेरी का परिणाम है? कुछ linq बयान एल 2 एस एन + 1 में शामिल होने से स्विच करने के लिए कारण हो सकता है। –

+1

डुप्लिकेट मार्कर: क्या आप इकाई ढांचे और linq के बीच एसक्यूएल के बीच अंतर जानते हैं? –

+0

@GertArnold जबकि ईएफ/एल 2 एस के LINQ भाग अक्सर समान प्रश्नों को कार्यात्मक रूप से डुप्लिकेट करते हैं, * इस * मामले में मेरा मानना ​​है कि आप पूरी तरह से सही हैं; वे डुप्लिकेट नहीं हैं। पुन: खोलने से। –

उत्तर

0

आपको अपने डेटा लोड के लिए सही विकल्प निर्धारित करना होगा।

options.LoadWith<Document>(d => d.Metadata); 

पर देखो this

पी.एस. Include केवल LINQToEntity के लिए।

+0

ऐसा लगता है कि यह जवाब होना चाहिए, लेकिन यह मेरे लिए काम नहीं करता है। मैंने dlo.LoadWith (पी => पी। चिल्ड्रेन) की कोशिश की। अभी भी कई डीबी हिट – Paul

+0

@Paul आपको parenttable का उपयोग करने की आवश्यकता नहीं है। क्या आपने LINQ2SQL द्वारा इकाई अभिभावक उत्पन्न किया है? तब जब आप माता-पिता से संदर्भ से अनुरोध करते हैं तो आपकी इकाई में पहले से ही बच्चे होते हैं। –

0

दूसरी क्वेरी तेज है ठीक है क्योंकि बच्चों को आबादी नहीं दी जा रही है।

और पहले एक धीमी गति से सिर्फ इसलिए बच्चे डाला जा रहा है है।

अपनी आवश्यकताओं को सर्वोत्तम रूप से फिट करने वाला एक चुनें, आप बस अपनी सुविधाओं को एक साथ नहीं रख सकते हैं!

संपादित करें:

@Servy रूप का कहना है:

अपने दूसरे क्वेरी में आप वास्तव में बच्चों के बारे में कोई जानकारी प्राप्त करने में नहीं कर रहे हैं। आपने प्रश्नों को बनाया है, लेकिन आपने वास्तव में उन प्रश्नों के परिणाम प्राप्त करने के लिए उन्हें निष्पादित नहीं किया है। यदि आप सूची को फिर से शुरू करना चाहते हैं, और उसके बाद प्रत्येक आइटम के बच्चों के संग्रह को पुन: सक्रिय करें, तो आप पहली क्वेरी के रूप में जितना समय लेते हैं उतना समय लगेगा।

1

मुझे यह पूरा करने के लिए सबसे तेज़ तरीका यह है कि सभी परिणामों को वापस करने के बाद सभी परिणामों को समूहित करें। सुनिश्चित करें कि आप पहली क्वेरी पर .ToList() करते हैं, ताकि दूसरी क्वेरी कई कॉल न करे।

यहां r होना चाहिए जो आप केवल एक डीबी क्वेरी के साथ पूरा करना चाहते हैं।

  var q = from p in parenttable 
        join c in childtable on p.id equals c.parentid 
        select c).ToList(); 
      var r = q.GroupBy(x => x.parentid).Select(x => new { id = x.Key, Children=x }); 
+1

एक जॉइन करने के बजाय और फिर एक समूह के बजाय, समूह समूह का उपयोग करें। – Servy

5

यह याद रखना महत्वपूर्ण है कि LINQ प्रश्नों आस्थगित निष्पादन में भरोसा करते हैं महत्वपूर्ण है। आपकी दूसरी पूछताछ में आप वास्तव में बच्चों के बारे में कोई जानकारी नहीं ले रहे हैं। आपने प्रश्नों को बनाया है, लेकिन आपने वास्तव में उन प्रश्नों के परिणाम प्राप्त करने के लिए उन्हें निष्पादित नहीं किया है। यदि आप सूची को फिर से चालू करना चाहते हैं, और उसके बाद प्रत्येक आइटम के Children संग्रह को पुन: सक्रिय करें, तो आप पहली क्वेरी के रूप में जितना समय लेते हैं, उसे देखते हैं।

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

var q = from p in parenttable 
     join child in childtable 
     on p.id equals child.parentid into children 
     select new Parent() 
     { 
      id = p.id, 
      Children = children.ToList(), 
     } 
return q.ToList() //SLOW 
+0

मुझे पता है कि सवाल LINQ से SQL के बारे में है, लेकिन मैंने सोचा कि मैं उल्लेख करता हूं कि यदि आप इकाई फ्रेमवर्क का उपयोग कर रहे हैं, तो 'बच्चों' पर 'ToList() 'की आवश्यकता नहीं है। –