2009-02-23 10 views
6

मुझे ado.net इकाई ढांचे में linq के साथ कुछ समस्याएं आ रही हैं।लिनक्स से उत्पन्न इकाइयों एसक्यूएल

var results = (from c in companies 
    where c.Name.StartsWith(letter) 
    select c); 

और कुछ इस तरह के रूप में SQL में अनुवाद किया जाता है: मूल रूप से क्या मैं कर रहा हूँ यह है

WHERE (CAST(CHARINDEX(@p, [Extent1].[Name]) AS int)) = 1 

जो ठीक है, लेकिन अभी यह बहुत धीमी गति से चलाता है मेरी मेज रिकॉर्ड के लाखों लोगों की है।

WHERE Name LIKE @p + '%' 

मैं उच्च और निम्न खोज रहा हूँ और करने के लिए या तो एक संग्रहीत प्रक्रिया या उपयोग इकाई एसक्यूएल ... का उपयोग

है वहाँ किसी भी छोड़कर किसी भी समाधान नहीं मिल सकता है: क्या मैं इसकी आवश्यकता उत्पन्न करने के लिए कुछ की तरह है linq के माध्यम से ऐसा करने का तरीका? संभावित रूप से linq प्रदाता इकाइयों के लिए linq विस्तार, या किसी भी तरह से आदेश पेड़ या उत्पन्न क्वेरी intercepting?

+0

यह जो मुझे बहुत कुछ भी जो एसक्यूएल उत्पन्न करता है के पक्ष में अपना संग्रहीत प्रक्रिया परत फेंक relunctant बनाता है बात इस तरह का है। –

उत्तर

2

वाह, यह करने का वास्तव में विचित्र तरीका है! ध्यान दें कि LINQ-to-SQL (इस मामले में) LIKE @p0 + '%' का उपयोग करता है ... बहुत विषम।

कौन सा ईएफ प्रदाता (डेटाबेस) आप उपयोग कर रहे हैं? एस क्यू एल सर्वर?

आप कहते हैं के रूप में, एक संग्रहीत प्रक्रिया काम है, लेकिन आप कि ... बहुत, बहुत अजीब नहीं करने के लिए होना चाहिए ...

+0

हां मैं SQL सर्वर 2005 का उपयोग कर रहा हूं। मैंने जो पढ़ा है, उससे LINQ से SQL एक SQLMethods क्लास प्रदान करता है जो SQL कार्य और ऑपरेटरों जैसे LIKE का खुलासा करता है लेकिन LINQ से Entities में ऐसी कोई चीज़ नहीं है। जाओ आंकड़े ... –

4

मैं नहीं किसी SQL विशेषज्ञ लेकिन यह अनुमान लगा रहा हूँ जाएगा दोनों वाक्यविन्यास:

कहां (कास्ट (CHARINDEX (@p, [Extent1] [नाम]) पूर्णांक के रूप में)।) = 1

और

जहां नाम की तरह @p + '%'

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

सुधार के लिए एक संभावित क्षेत्र: बीमा करें कि आपने जिस कॉलम पर खोज कर रहे हैं उसे सूचीबद्ध किया है।

alt text http://download.binaryocean.com/plan1.gif

alt text http://download.binaryocean.com/plan2.gif

+1

बशर्ते आपके पास नोट/नाम कॉलम पर एक अनुक्रमणिका है और कार्डिनलिटी बहुत कम नहीं है, तो इसका उपयोग LIKE '%' क्वेरी पर किया जाएगा। मुझे यकीन नहीं है कि क्वेरी ऑप्टिमाइज़र एक CAST (CHARINDEX()) ऑपरेशन के लिए अनुक्रमणिका का उपयोग करने में सक्षम होगा। –

+1

मेरे पास मेरे डेटाबेस के नाम कॉलम पर एक अनुक्रमणिका है। LIKE एक इंडेक्स स्कैन करता है, जेनरेटेड एसक्यूएल (CHARINDEX) एक टेबल स्कैन करता है, यही कारण है कि इसमें इतना समय लगता है। –

0

"लेटर" एक चार है? यदि आप इसे एक स्ट्रिंग बनाते हैं, तो क्या होता है?

var results = (from c in companies 
    where c.Name.StartsWith(letter.ToString()) 
    select c); 
+0

यह एक स्ट्रिंग है ... –

0

मैं इस वाक्य रचना के बजाय

Name.Substring(0, 1) == "E" 

यह एसक्यूएल

WHERE N'E' = (SUBSTRING([Name], 0 + 1, 1)) 

उत्पन्न होता है हो सकता है कि यह और अधिक कुशल है उपयोग करने की कोशिश?

+0

हाँ मैंने भी कोशिश की है ... मुझे लगता है कि यह इसके बारे में भी चला। –

1

यह लिंक से इकाइयों के साथ known issue है। पसंद के विपरीत, स्पष्ट रूप से यह निर्माण इंडेक्स का उपयोग नहीं करता है।

हमें सबस्ट्रिंग (जो सब्सट्रिंग में अनुवाद करता है) का उपयोग करके कुछ सफलता मिली है। निष्पादन योजना समान है, लेकिन हमारे मामले में क्वेरी बहुत तेज़ी से निष्पादित होती है।

यह एक और "मुझे यकीन है कि यह एफई 2 में ठीक किया जाएगा हूँ" ... :-(

0

आप एक असली की तरह लिंक की इकाइयां करने के लिए काफी आसानी से उपयोग कर सकते हैं

यहाँ क्या बनाने के लिए आवश्यक है यह काम:

इस टैग में अपने edmx को

<Function Name="String_Like" ReturnType="Edm.Boolean"> 
     <Parameter Name="searchingIn" Type="Edm.String" /> 
     <Parameter Name="lookingFor" Type="Edm.String" /> 
     <DefiningExpression> 
     searchingIn LIKE lookingFor 
     </DefiningExpression> 
    </Function> 

जोड़ें:

edmx: edmx/edmx: रनटाइम/edmx: ConceptualModels/स्कीमा

इसके अलावा <schema namespace="" /> विशेषता में नाम स्थान याद

फिर ऊपर नाम स्थान में एक विस्तार वर्ग जोड़ें:

public static class Extensions 
{ 
    [EdmFunction("DocTrails3.Net.Database.Models", "String_Like")] 
    public static Boolean Like(this String searchingIn, String lookingFor) 
    { 
     throw new Exception("Not implemented"); 
    } 
} 

यह एक्सटेंशन विधि अब EDMX फ़ंक्शन पर मैप करेगी।

अधिक यहाँ जानकारी: http://jendaperl.blogspot.be/2011/02/like-in-linq-to-entities.html