2010-08-17 17 views
18

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

उत्तर

30

मान लें कि आपके पास एक से कई रिश्तों के साथ दो इकाइयां हैं: ग्राहक और आदेश, जहां प्रत्येक ग्राहक के पास कई ऑर्डर हो सकते हैं।

ग्राहक इकाई को लोड करते समय, इकाई फ्रेमवर्क आपको ग्राहक के ऑर्डर संग्रह को या तो लोड या आलसी लोड करने की अनुमति देता है। आप उत्सुक लोड करने के लिए आदेश संग्रह चुनते हैं, तो जब आप डेटाबेस से बाहर एक ग्राहक को पुनः प्राप्त इकाई की रूपरेखा एसक्यूएल कि दोनों ग्राहक के बारे में जानकारी और एक क्वेरी में ग्राहक के आदेश को पुन: प्राप्त उत्पन्न होगा। हालांकि, यदि आप ऑर्डर संग्रह को आलसी लोड करना चुनते हैं, तो जब आप डेटाबेस एंटिटी फ्रेमवर्क से ग्राहक को पुनर्प्राप्त करते हैं तो SQL उत्पन्न होगा केवल ग्राहक की जानकारी खींचता है (यदि आप ग्राहक के ऑर्डर तक पहुंचते हैं तो एंटीटी फ्रेमवर्क तब एक अलग SQL कथन उत्पन्न करेगा बाद में अपने कोड में संग्रह)।

उत्सुक लोडिंग का उपयोग करने के लिए निर्धारित करना और आलसी लोडिंग का उपयोग कब करना है, उन सभी चीजों के साथ आता है जो आप पुनर्प्राप्त करने वाली संस्थाओं के साथ करते हैं। यदि आपको पता है कि आपको केवल ग्राहक की जानकारी की आवश्यकता है, तो आपको ऑर्डर संग्रह को आलसी लोड करना चाहिए (ताकि SQL क्वेरी केवल ग्राहक की जानकारी पुनर्प्राप्त करके सक्षम हो)। इसके विपरीत, यदि आप जानते हैं कि आप तो आप आदेश उत्सुक-लोड करना चाहिए, एक ग्राहक के आदेश के माध्यम से पार करने के लिए करनी होगी (ऐसा आप अपने आप को एक अतिरिक्त डेटाबेस हिट एक बार आप अपने कोड में ग्राहक के आदेश का उपयोग बचा सकते हैं)।

पीएस आलसी लोडिंग का उपयोग करते समय बहुत सावधान रहें क्योंकि इससे एन + 1 समस्या हो सकती है। उदाहरण के लिए, मान लीजिए कि आपके पास एक ऐसा पृष्ठ है जो ग्राहकों और उनके आदेशों की एक सूची प्रदर्शित करता है। हालांकि, आप आदेश प्राप्त करते समय आलसी लोडिंग का उपयोग करने का निर्णय लेते हैं। जब आप ग्राहक संग्रह पर फिर से शुरू होते हैं, तो प्रत्येक ग्राहक के ऑर्डर पर, आप प्रत्येक ऑर्डर के लिए अपने ऑर्डर संग्रह में आलसी लोड के लिए डेटाबेस हिट करेंगे। इसका अर्थ यह है कि एन ग्राहकों के लिए, आपके पास केवल 1 डेटाबेस हिट के बजाय एन 1 डाटाबेस हिट (सभी डेटाबेस लोड करने के लिए 1 डेटाबेस हिट होगा, फिर आपके डेटाबेस को प्रत्येक लोड करने के लिए हिट होगा) (जो एक प्रश्न में सभी ग्राहकों और उनके आदेशों को पुनः प्राप्त कर लेगा)।

+0

आपकी प्रतिक्रिया स्पष्ट नहीं है। आप ग्राहक से संबंधित एक प्रश्न और ग्राहक से संबंधित सभी आदेशों के साथ लोड करने के लिए उत्सुक लोडिंग का उपयोग नहीं कर सकते हैं। उत्सुक लोडिंग के साथ आप ऑर्डर और संबंधित ग्राहक को पुनर्प्राप्त कर सकते हैं। –

+0

@ बुजियो यह मेरे लिए पर्याप्त स्पष्ट था। अनुमोदित, मैं पहले से ही अंतर जानता हूँ। लेकिन फिर भी, यह इमो काम करता है। –

+0

@Erik कृपया सेकेंड पैराग्राफ पढ़ें। प्रतिक्रिया में एक गलती है। "डेटाबेस एंटिटी फ्रेमवर्क से ग्राहक एसक्यूएल उत्पन्न करेगा जो ग्राहक की जानकारी और ग्राहक के आदेश दोनों को एक प्रश्न में पुनर्प्राप्त करेगा" गलत है। यह केवल एक आदेश पुनर्प्राप्त करेगा सभी आदेश नहीं। –

6

उत्सुक लोडिंग का लक्ष्य N+1 Selects ओआरएम के लिए समस्या को हल करने का इरादा है। लघु संस्करण यह है: आप सीधे संस्थाओं में से कुछ संख्या को पुनः प्राप्त करने जा रहे हैं और आप जानते हैं कि आप पुनः प्राप्त संस्थाओं के माध्यम से कुछ संबंधित गई चीजों का उपयोग किया जाएगा, तो यह ज्यादा अधिक पुनः प्राप्त करने के कुशल सभी संबंधित संस्थाओं सामने से एक में है आलसी लोडिंग के माध्यम से उन्हें क्रमशः पुनर्प्राप्त करने की तुलना में पास करें।

17

आप एसक्यूएल दुनिया से आते हैं के बारे में शामिल हों लगता है।

आप एक ग्रिड में दिखाने के लिए है, तो 10 के आदेश और ग्राहक है कि आदेश डाल आप 2 विकल्प हैं:

1) आलसी लोड (= 11 queryes = धीमा प्रदर्शन के)

एफई होगा ग्राहक डेटा पुनर्प्राप्त करने के लिए आदेशों और प्रत्येक आदेश के लिए एक क्वेरी पुनर्प्राप्त करने के लिए एक क्वेरी को गोली मार दी।

Select * from order where order=1 
+ 
10 x (Select * from customer where id = (order.customerId)) 

1) उत्सुक लोड (= 1 क्वेरी = उच्च प्रदर्शन)

एफई आदेश और ग्राहकों को एक में शामिल हों के साथ पुनः प्राप्त करने के किसी एक क्वेरी गोली मार दी जाएगी।

Select * from orders INNER JOIN customers on orders.customerId=customer.Id where order=1 

पुनश्च: जब आप डाटाबेस से एक वस्तु पुनः प्राप्त करने, वस्तु एक कैश में संग्रहीत किया जाता है, जबकि संदर्भ सक्रिय है। उदाहरण के लिए मैंने LAZY LOAD, के साथ बनाया है यदि सभी 10 ऑर्डर एक ही ग्राहक से संबंधित हैं आपको केवल 2 क्वेरी दिखाई देगी क्योंकि जब आप किसी ऑब्जेक्ट को पुनर्प्राप्त करने के लिए ईएफ से पूछते हैं तो ईएफ जांच करेगा कि ऑब्जेक्ट कैश में है या नहीं और अगर ऐसा लगता है कि यह डीबी को एक और एसक्यूएल क्वेरी नहीं फेंक देगा।

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