2016-05-13 4 views
6

मेरे पास ऑब्जेक्ट्स (सूची-अभिभावक क्लास) की एक सूची के भीतर वस्तुओं की एक सूची है, जिसमें इसकी वस्तुओं में से एक नेस्टेड सूची (सूची-चाइल्ड क्लास) है। सूची-चाइल्ड क्लास को पॉप्युलेट करने के लिए मैंने नीचे दिखाए गए फ़ोरैच लूप का उपयोग किया है। मैंने नीचे एक शोक क्वेरी भी निहित की है।सी # में किसी सूची में एक सूची पॉप्युलेट करना फ़ोरैच लूप का उपयोग नहीं कर रहा है। बेहतर तरीका?

इस बिंदु पर मुझे कुछ प्रदर्शन समस्याएं हैं और मुझे लगता है कि ऐसा करने का एक बेहतर तरीका है जिसे मैं अभी नहीं ढूंढ रहा हूं।

प्रश्न: मैं इसे बेहतर/तेज़ कैसे कर सकता हूं?

नोट - यह एक वेब आधारित .NET एमवीसी अनुप्रयोग सी # में लिखा गया है। मैं एक एसक्यूएल डेटाबेस में ईएफ का उपयोग करता हूं।

public class ParentClass 
{ 
    public int pcid { get; set; } 
    public List<ChildClass> ChildClassList { get; set; } 
} 

public class ChildClass 
{ 
    public int pcid { get; set; } 
    public int ccid { get; set; } 
} 

public class DoWork 
{ 
    public void ExampleMethodForEach() 
    { 
     List<ParentClass> ParentClassList = new List<ParentClass>(); 

     foreach(ParentClass a in ParentClassList) 
     { 
      a.ChildClassList = EFDatabase2.where(b => b.pcid == a.pcid).select(b => b.ccid).ToList(); 
     } 
    } 

    public void ExampleMethodLinq() 
    { 
     var ParentClassList = (from a in EFDatabase 
           select new ParentClass 
           { 
            ccid = a.ccid, 
            pcid = (from b in EFDatabase2 
              where b.pcid == a.pcid 
              select b.ccid).ToList() 
            //something like this were I nest a query 
           }).ToList(); 
    } 
} 
+0

यदि आपके पास * डेटाबेस * के साथ प्रदर्शन समस्या है, तो यह * नहीं * 'सूची ',' foreach' आदि है लेकिन * डेटाबेस * दोष है। अंतिम पूछताछ क्या है? क्वेरी कितने रिकॉर्ड लाती है? सूची के भीतर * सूची के मामले में, आप जितनी कॉल कर सकते हैं उतनी कॉल करने का प्रयास करें: क्या आप * एक बार * में सभी डेटा ला सकते हैं और फिर उन्हें अपनी इच्छित संरचना में व्यवस्थित कर सकते हैं? –

+0

जो मैंने पाया था, वह था कि डेटाबेस को मारने की संख्या कितनी बार संभवतः मुद्दों का कारण बन रही थी। मेरे वर्तमान ऐप में मैं डेटा को मेमोरी में खींच रहा हूं, फिर फोरच लूप चला रहा हूं। यह बेहतर प्रदर्शन करता है लेकिन ऐसा लगता है कि यह थोड़ा भारी हैरान है। मैं सोचता रहता हूं कि मैं सब एक बड़ी क्वेरी में किया जा सकता है। – KungFuMaster

+0

जहां तक ​​रिकॉर्ड्स की मात्रा है, यह अपेक्षाकृत छोटा है, हम एक या दो बार वापस लौट रहे हैं, लेकिन फिर प्रत्येक में कई सूचियां हैं जिनमें 3 - 10x अधिक रिकॉर्ड होंगे। इसके अलावा इसे खींचने के लिए सवाल थोड़ा और जटिल हैं। तो मेरी स्थिति के विवरण में उतरना यह शायद इतना आसान नहीं है। प्रश्न: क्या आपको लगता है कि उपरोक्त विधियां इस स्थिति को हल करने के सामान्य/सामान्य तरीके हैं? – KungFuMaster

उत्तर

2

संबंधपरक डेटाबेस और LINQ के साथ काम करते समय सबसे अच्छा तरीका का उपयोग डेटा से संबंधित करने के लिए करता है। आपके मामले में, सबसे उपयुक्त group join है:

var ParentClassList = 
    (from p in EFDatabase 
    join c in EFDatabase2 on p.pcid equals c.pcid into children 
    select new ParentClass 
    { 
     pcid = p.pcid, 
     ChildClassList = 
      (from c in children 
       select new ChildClass 
       { 
        pcid = c.pcid, 
        ccid = c.ccid 
       }).ToList() 
    }).ToList(); 

जो आप एक अच्छे तेज एकल डाटाबेस क्वेरी देना चाहिए।

पीएस आशा है कि आपका EFDatabase और EFDatabase2 चर एक और एक ही डेटाबेस के अंदर दो तालिकाओं का संदर्भ लें।

+0

इस समाधान ने मुझे सबसे अच्छा प्रदर्शन दिया। इसे सही उत्तर के रूप में चिह्नित करना। – KungFuMaster

0

आप अपने डेटाबेस को कई बार मार रहे हैं। आपके पास एन + 1 मुद्दा है।

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

अभिभावक आईडी की सरणी का उपयोग करके सभी बच्चों को लोड करने के बाद, उन्हें मूल आईडी के रूप में मूल आईडी का उपयोग करके ToLookup का उपयोग करके लुकअप पर मानचित्र करें और माता-पिता को बच्चों की सूची असाइन करने के लिए एक foreach का उपयोग करें।

var parents = EFDatabase2.Parents.Where(...).Select(p => new ParentClass { pcid = p.pcid }).ToList(); 
var ids = parents.Select(p => p.pcid).ToArray(); 
var children = EFDatabase2.Children.Where(c => ids.Contains(c.ccid)).Select(c => new ChildClass { pcid = c.pcid, ccid = c.ccid }).ToLookup(c => c.pcid); 

foreach (var parent in parents) 
{ 
    parent.Children = children[parent.pcid]; 
} 

इस मामले में, आप केवल अपने डेटाबेस में दो प्रश्न पूछेंगे।

+0

यह कुछ उदाहरणों में मैं जो कर रहा हूं उससे बहुत समान है और प्रदर्शन "सभ्य" है, हालांकि मुझे लगता है कि मैं linq पर निर्भर हूं और सूची बहुत अधिक है। जैसा कि आपने वर्णन किया है, मैं कोशिश करूंगा। – KungFuMaster

+0

यह बहुत संदिग्ध है कि आपको LINQ और सूची के बिना प्रदर्शन में कोई वास्तविक सुधार मिलेगा।प्रोपेम जैसा है कि पियरे-अलैन ने आपके कई डीबी प्रश्नों में कहा था। सबसे अच्छा तरीका है कि आप अपने डेटाबेस से सबकुछ पूछें (जैसे संग्रहीत प्रक्रिया के माध्यम से) और फिर इसे अपने डेटा पर मैप करें। एक और चीज आपको सत्यापित करनी चाहिए कि आपके प्रश्नों के लिए आपके डेटाबेस में उचित अनुक्रमणिका हैं, हो सकता है कि आपकी प्रदर्शन समस्या हो। –

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