2013-06-11 10 views
7

एएसपीनेट में प्रति क्वेरी डीबीकॉन्टेक्स्ट बनाने से ईएफ केवल अपने कैश से डेटा पढ़ता है, या क्या यह हर बार पूरे सेट के लिए डीबी से पूछता है? मैं प्रति एपडोमेन के मेटाडेटा कैशिंग के बारे में जानता हूं, लेकिन केवल डेटा के बारे में क्या?क्या डीएफ कॉन्टेक्स्ट के विभिन्न उदाहरणों के बीच ईएफ कैश इकाइयों को कैश करता है?

संदर्भ: एमवीसी 4 + वेब एपीआई फ्रंटएंड के साथ डेटा अधिग्रहण और विज़ुअलाइजेशन एप्लिकेशन, "उच्च मात्रा" को कॉल नहीं करेगा, लेकिन बहुत से प्रश्न कुछ छोटे समय सीमा में डेटा के समान सेट लौटाते हैं।

+0

मुझे नहीं लगता कि इतना है कि डेटा में कैश किया गया है है संस्थाएं हमेशा पूछती हैं डीबी –

उत्तर

13

इकाई फ्रेमवर्क में प्रति डेटा उदाहरण प्रति कैश नहीं है, प्रति संदर्भ उदाहरण केवल कैश है।

यदि आप प्रति अनुरोध या क्वेरी के साथ एक नया संदर्भ बनाते हैं तो आप एक खाली कैश से शुरू करते हैं और ईएफ डाटाबेस से डेटा लाएगा।

इसके अलावा, "कैश प्रति संदर्भ उदाहरण" शब्द भ्रामक हो सकता है क्योंकि इसका मतलब यह नहीं है कि यदि ईएफ संदर्भ संदर्भ कैश में पहले ही लोड हो चुकी है तो ईएफ डेटाबेस से क्वेरी नहीं चलाएगा। ,

  • हर LINQ करने वाली संस्थाओं क्वेरी एक DbSet<T> पर या आम तौर पर एक IQueryable<T> पर एक डेटाबेस क्वेरी चलेंगे: जिस तरह से है कि यह कैसे काम करता है कैश और आप इसे कैसे (या नहीं) का लाभ उठा सकें पीछा कर रहा है इससे कोई फर्क नहीं पड़ता कि संस्थाएं संदर्भ में पहले से मौजूद हैं या नहीं। लेकिन यदि एक क्वेरी वाली क्वेरी के साथ एक इकाई पहले से मौजूद संदर्भ में मौजूद है, तो ईएफ उस क्वेरी के परिणाम को फेंक देगा और कैश किए गए इकाई आवृत्ति को वापस कॉलर पर वापस कर देगा।

    यह जांच करता है कि के बाद यह कुंजी मौजूद है, तो यह जांच करता है। (जटिल प्रश्नों के लिए - उदाहरण के प्रश्नों के लिए है कि एक Include होते हैं -। यह पहले यह चेक नहीं कर सकते, क्योंकि यह पता नहीं कर सकते हैं जो संस्थाओं और मुख्य मान लौटाए जाएंगे)

    डिफ़ॉल्ट व्यवहार है कि (MergeOptionAppendOnly है)। आप इस व्यवहार को OverwriteChanges और अन्य विकल्पों में बदल सकते हैं, मेरा मानना ​​है कि उनमें से कोई भी LINQ क्वेरीज हमेशा डेटाबेस प्रश्न जारी नहीं करेगा।

  • सिर्फ उसके प्रमुख द्वारा एक इकाई की क्वेरी आप उपयोग कर सकते हैं GetObjectByKey या Find (DbContext के साथ) जो पहले की जाँच करेगा कि अगर कुंजी के साथ इकाई पहले से संदर्भ में कैश किया गया है और उसके बाद इस संचित वस्तु लौटने। यदि नहीं, तो यह लोड करने के लिए डेटाबेस क्वेरी चलाएगा।

  • आप ईएफ के चेंजट्रैकर से पूछ सकते हैं, यह विशेष रूप से DbContext के साथ समर्थित है जहां आपके पास DbSet<T>.Local संग्रह के माध्यम से संदर्भ कैश तक पहुंच है।

    समस्या यह है कि Local पर कोई प्रश्न न मिलने पर डेटाबेस को स्वचालित रूप से क्वेरी करने के लिए कोई तर्क नहीं है। आपको यह तर्क मैन्युअल रूप से लिखना होगा। यहां तक ​​कि बड़ी समस्या यह है कि Local पर एक क्वेरी LINQ-to-Objects है और LINQ-to-Entities (LocalIQueryable<T> लागू नहीं करती है, केवल IEnumerable<T>), इसलिए आपको Local पर कार्य करने के लिए अक्सर अपने प्रश्नों को फिर से लिखना होगा - उदाहरण के लिए आप Include यहाँ उपयोग नहीं कर सकते हैं, अपने किसी भी EntityFunctions उपयोग नहीं कर सकते, तो आप आदि केस संवेदनशीलता के बारे में स्ट्रिंग तुलना के लिए अलग व्यवहार, आदि, मिल जाएगा

+0

महान स्पष्टीकरण के लिए धन्यवाद।अब तक, मैंने पूरी तरह से इस तथ्य को याद किया था कि कैश किए गए संस्करण का उपयोग किया जा सकता है, भले ही डेटाबेस के विरुद्ध प्रश्न जारी किए जाएं। मैंने SQL सर्वर प्रोफाइलर का उपयोग किया और उन प्रश्नों को देखा जो मेरे आवेदन में ताजा डेटा नहीं लौटा !? अंत में मुझे पता चला कि मेरा कस्टम सदस्यता प्रदाता अनुरोध के बीच ढांचे द्वारा जारी रखा गया था और इसलिए संदर्भ उदाहरण भी रखा गया था। अन्य कोड संदर्भों में चल रहा था और चीजें पूरी तरह से गड़बड़ हो गईं। –

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