2017-04-24 11 views
5

मैं ईएफ 6 द्वारा फंस गया हूं .... मेरे पास एक वेब एप्लिकेशन है जो प्रदर्शन के मामले में बहुत बुरी तरह व्यवहार करता है। विश्लेषण करते समय, मैंने पाया कि अपराधियों में से एक मेरा तरीका है जो जांचता है कि एक संग्रह ईएफ 6 इकाई पर खाली है या नहीं।ईएफ 6 - जो भी मैं उम्मीद करता हूं वह नहीं कर रहा .अन्य()

मूल रूप से, मेरे पास है:

public partial class BaseEntity 
{ 
    public int BaseEntityId { get; set; } 
    public string Name { get; set; } 

    // a few more properties, of no concern here.... 

    // a lazily loaded collection of subitems   
    public virtual ICollection<Subitem> Subitems { get; set; } 
} 

public partial class Subitem 
{ 
    public int SubitemId { get; set; } 
    public int BaseEntityId { get; set; } 
    public string Name { get; set; } 

    // a few more properties, of no concern here.... 
} 

मेरे ऐप में, मैं जाँच करने के लिए किया जाए या नहीं BaseEntity की दी गई उदाहरण "खाली" है की जरूरत है - जो कोई subitems होने के रूप में परिभाषित किया गया है। तो मैं दूसरा आंशिक वर्ग फ़ाइल के लिए इस विधि CheckIfEmpty कहा:

public partial class BaseEntity 
{ 
    public bool IsEmpty 
    { 
     return !Subitems.Any(); 
    } 
}   

अब एक BaseEntity सैकड़ों या subitems के हजारों हो सकता है - तो मैं या नहीं, वहाँ किसी भी subitems थे की जांच करने के लिए सबसे कारगर तरीका उपयोग करना चाहता था । मेरे धारणा था कि एक संग्रह है कि डेटाबेस से अभी तक लोड नहीं हो गया है पर .Any() बुला मूल रूप से एक

IF EXISTS(SELECT * FROM dbo.Subitems) ...... 

एसक्यूएल कॉल में अनुवाद होगा - या कुछ और उन पंक्तियों के साथ - बस अगर किसी भी आइटम अस्तित्व में देखने के लिए जाँच - या नहीं। मैंने विशेष रूप से .Any().Count > 0 से अधिक चुना क्योंकि मुझे पता है कि गिनती की जांच करने के लिए पूरे संग्रह की गणना करने की आवश्यकता होगी और इस तरह मैं अत्यधिक जानना चाहता हूं जब मैं जानना चाहता हूं कि कोई वस्तु मौजूद है या नहीं।

मैं जानना चाहता की जरूरत नहीं है कितने मौजूद हैं, और न ही मैं उनके विवरण में दिलचस्पी है - सिर्फ एक सरल हाँ या नहींis empty? प्रश्न पर्याप्त होगा करने के लिए।

मेरा बड़ा विस्मय (और bedazzlement) करने के लिए, यह पता चला है EF6 एक SELECT बयान है कि पूरे संग्रह को लोड करता है में इस सरल .Any() कॉल बदल जाता है! - कि निश्चित रूप से नहीं क्या मैं के लिए सौदेबाजी की थी है ......

तो वहाँ किसी भी आसान तरीका बस जाँच करने के लिए है अगर एक नहीं अभी तक भरी हुई संग्रह किसी भी मान होते हैं - या नहीं - बिना डेटाबेस से पूरा संग्रह लोड हो रहा है ??

+0

सभी वस्तुओं से पहले ही 'कॉलिंग Subitems' भार' कोई भी नहीं पहुंचा है, इस तरह आलसी लोडिंग लागू की गई है। पहली बार जब आप 'सबिटम्स' तक पहुंचते हैं तो इसे लोड किया जाता है। मैं आलसी लोडिंग का उपयोग कभी नहीं करने की कोशिश करता हूं, लेकिन यह मेरे कोड को जटिल करता है: मैं जितनी जल्दी हो सके संदर्भ को बंद कर देता हूं, और 'db.Subitem.Any (si => si। BaseEntityId == .. के लिए एक और दूसरा खोलता हूं। ।) ' – Kobi

+0

' सबइटेम्स 'एक' आईसीओलेक्शन 'है। यह काम कर सकता है क्योंकि आप उम्मीद करते हैं कि यह 'IQueryable' था (मुझे यकीन नहीं है, और मुझे नहीं पता कि आलसी लोडिंग' IQueryable' के साथ काम कर सकती है) –

+1

एक उत्सुक लोडिंग दृष्टिकोण का उपयोग करके और डीबीसेट से पूछताछ करके, आप आप जो चाहते हैं उसे प्राप्त करें: संदर्भ। ()।कोई(); में अनुवाद किया जाता है: चयन मामला जब मौजूद है ( का चयन करें 1 [TEntity] के रूप में [एम] से) तो कास्ट (1 बिट) और कास्ट (0 के रूप में बीआईटी) अंत – alessalessio

उत्तर

5

एक उत्सुक लोड हो रहा है दृष्टिकोण का उपयोग कर और DbSet क्वेरी करने से, आप आप क्या चाहते हैं पाने:

context.Set<TEntity>().Any();

में अनुवाद किया जाता है:

SELECT CASE WHEN EXISTS (SELECT 1 FROM [TEntity] AS [m]) THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) END 
+0

फिर से धन्यवाद - महान जवाब। मैंने इसे 'context.Subitems.Any (si => si.BaseEntityId == 42) का उपयोग करने के लिए थोड़ा संशोधित किया है; और यह भी बहुत अच्छी तरह से काम करता है। महान दृष्टिकोण - धन्यवाद! –

+0

खुशी हुई इससे मदद मिली। चियर्स – alessalessio

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