2011-01-18 18 views
8

मेरी एंटीटी फ्रेमवर्क 4.0 आधारित डेटाबेस परत प्रोफाइलिंग के बाद मुझे एक प्रमुख LINQ कोई भी() मैं यह देखने के लिए उपयोग करता हूं कि डेटाबेस में पहले से मौजूद एक इकाई मौजूद है या नहीं। कोई भी() चेक इकाई को बचाने से धीमी गति के आदेश करता है। डेटाबेस में अपेक्षाकृत कुछ पंक्तियां हैं और कॉलम की जांच की जा रही है।एंटिटी फ्रेमवर्क

मैं एक सेटिंग समूह के होने की जाँच करने के लिए निम्न LINQ का उपयोग करें:

from sg in context.SettingGroups 
where sg.Group.Equals(settingGroup) && sg.Category.Equals(settingCategory) 
select sg).Any() 

यह निम्नलिखित एसक्यूएल उत्पन्न करता है (अतिरिक्त मेरी एसक्यूएल प्रोफाइलर का दावा क्वेरी दो बार निष्पादित किया जाता है):

exec sp_executesql N'SELECT 
CASE WHEN (EXISTS (SELECT 
    1 AS [C1] 
    FROM [dbo].[SettingGroups] AS [Extent1] 
    WHERE ([Extent1].[Group] = @p__linq__0) AND ([Extent1].[Category] = @p__linq__1) 
)) THEN cast(1 as bit) WHEN (NOT EXISTS (SELECT 
    1 AS [C1] 
    FROM [dbo].[SettingGroups] AS [Extent2] 
    WHERE ([Extent2].[Group] = @p__linq__0) AND ([Extent2].[Category] = @p__linq__1) 
)) THEN cast(0 as bit) END AS [C1] 
FROM (SELECT 1 AS X) AS [SingleRowTable1]',N'@p__linq__0 nvarchar(4000),@p__linq__1 nvarchar(4000)',@p__linq__0=N'Cleanup',@p__linq__1=N'Mediator' 

अभी मैं केवल इस समस्या को हल करने के लिए संग्रहीत प्रक्रियाओं को बनाने के बारे में सोच सकता हूं, लेकिन मैं निश्चित रूप से कोड को LINQ में रखना पसंद करूंगा।

क्या ईएफ के साथ इतनी "मौजूदा" जांच तेजी से चलाने का कोई तरीका है?

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

उत्तर

0

समस्या इकाई फ्रेमवर्क (कम से कम ईएफ 4) बेवकूफ एसक्यूएल उत्पन्न कर रहा है। निम्न कोड कम से कम दर्द के साथ सभ्य एसक्यूएल उत्पन्न करने लगता है।

public static class LinqExt 
{ 
    public static bool BetterAny<T>(this IQueryable<T> queryable, Expression<Func<T, bool>> predicate) 
    { 
     return queryable.Where(predicate).Select(x => (int?)1).FirstOrDefault().HasValue; 
    } 

    public static bool BetterAny<T>(this IQueryable<T> queryable) 
    { 
     return queryable.Select(x => (int?)1).FirstOrDefault().HasValue; 
    } 

} 

तो फिर तुम कर सकते हैं:

(from sg in context.SettingGroups 
where sg.Group.Equals(settingGroup) && sg.Category.Equals(settingCategory) 
select sg).BetterAny() 

या यहाँ तक कि:

context.SettingGroups.BetterAny(sg => sg.Group.Equals(settingGroup) && sg.Category.Equals(settingCategory)); 
0

मुझे पता है कि यह एक दुखी समाधान लगता है, लेकिन यदि आप किसी के बजाय गणना का उपयोग करते हैं तो क्या होता है?

+0

मैं इसे एक कोशिश दे देंगे। – Holstebroe

0

क्या आपने उस समय के विरुद्ध जेनरेट किए गए चयन कथन को निष्पादित करने का समय चुना है, जिसे आप उम्मीद करेंगे कि आप क्या उम्मीद करेंगे/उत्पादन करना चाहते हैं? यह संभव है कि यह उतना बुरा नहीं है जितना दिखता है।

अनुभाग

SELECT 
1 AS [C1] 
FROM [dbo].[SettingGroups] AS [Extent1] 
WHERE ([Extent1].[Group] = @p__linq__0) AND ([Extent1].[Category] = @p__linq__1) 

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

1

समूह & श्रेणी द्वारा डेटाबेस तालिका "सेटिंग समूह" में अनुक्रमणिका जोड़ने का प्रयास करें।

बीटीडब्ल्यू, क्या यह समान एसक्यूएल उत्पन्न करता है?

var ok = context.SettingGroups.Any(sg => sg.Group==settingGroup && sg.Category==settingCategory); 
+0

हां, एक अनुक्रमणिका का उपयोग करें। सेटिंग समूह (समूह, श्रेणी) पर इंडेक्स IX_SettingGroups_GC बनाएं – Ben

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