2009-12-17 11 views
13

यह कार्यों में LINQ करने वाली एसक्यूएल:एंटिटी फ्रेमवर्क LINQ कथन में ToString() का उपयोग करने में सक्षम क्यों नहीं होगा?

var customersTest = from c in db.Customers 
       select new 
       { 
        Id = c.Id, 
        Addresses = from a in db.Addresses where c.Id.ToString() == 
         a.ReferenzId select a 
       }; 

foreach (var item in customersTest) 
{ 
    Console.WriteLine(item.Id); 
} 

लेकिन इकाई की रूपरेखा में एक ऐसी ही उदाहरण के लिए, एक त्रुटि संदेश कि मूल रूप से कहना है कि यह नहीं "एसक्यूएल इसका अनुवाद" कर सकते हैं हो जाता है यहाँ है जर्मन में मूल त्रुटि संदेश: erkennt 'संस्थाओं को LINQ'

"मर Methode 'System.String ToString()' nicht, अंड Methode kann diese nicht einen Speicherausdruck में 0 übersetztवेरडन। "

अनुवाद:।

" 'संस्थाओं को LINQ' विधि 'System.String ToString()', इस विधि एक स्मृति अभिव्यक्ति में अनुवाद नहीं किया जा सकता है नहीं पहचानता है

किसी को भी कैसे हम इकाई की रूपरेखा में काम करते हैं या समझाने के लिए क्यों यह टी हो जाता बयान इस तरह का हो सकता है पर किसी भी प्रकाश डाला सकता है उसकी गलती?

+0

क्रमांक एक स्ट्रिंग पहले से ही है? निश्चित नहीं है कि इससे ईएफ को कोई समस्या क्यों होगी, लेकिन त्रुटि संदेश यह इंगित करता है कि यह ठोकर खा रहा है। आप चीज स्ट्रिंग करेंगे। ToString() बहुत तेज़ी से काम करेगा: पी –

+0

आईडी एल 2 एस उदाहरण में एक पूर्णांक है। हमारे असली ईएफ उदाहरण में यह एक GUID है। दिलचस्प है ToString() इंटेलिजेंस में है और यह संकलित करता है लेकिन उस रनटाइम त्रुटि को प्राप्त करता है। –

+0

@Edward Tanguay: मैं बस अपने questione देखा और एक जवाब जोड़ दिया है, मुझे आशा है कि यह अभी भी इस तरह के एक लंबे समय के बाद भी उपयोगी है ... – Matt

उत्तर

9

बस शब्दों में कहें: LINQ से Entities को आपके आईडी प्रकार से एक स्ट्रिंग में रूपांतरण के बारे में पता नहीं है।

c.ID का प्रकार क्या है? क्या कोई कारण है कि यह आईडी के लिए एक प्रकार का है, लेकिन ReferenzId के लिए दूसरा? यदि संभव हो, तो उन्हें एक ही प्रकार बनाएं, जिस बिंदु पर आपको अब कोई समस्या नहीं होगी। मुझे नहीं पता कि LINQ से इकाइयों में रूपांतरण करने के अन्य तरीके हैं - लेकिन हो सकते हैं - लेकिन प्रकारों को संरेखित करना क्लीनर होगा।

वैसे, यह वास्तव में लग रहा है कि यह एक में शामिल होने की तरह है:

var query = from c in db.Customers 
      join a in db.Addresses on c.Id equals a.ReferenzId into addresses 
      select new { Id = c.Id, Addresses = addresses }; 

संपादित करें: अपने टिप्पणी पर प्रतिक्रिया देने - ToString IntelliSense में प्रकट होता है क्योंकि संकलक कोई वास्तविक विचार क्या आपकी क्वेरी मतलब करने के लिए या जा रहा है है इसका अनुवाद कैसे किया जाएगा। यह पूरी तरह से मान्य सी # है, और एक मान्य अभिव्यक्ति वृक्ष उत्पन्न कर सकता है - यह सिर्फ इतना है कि ईएफ को यह अभिव्यक्ति पेड़ को SQL में परिवर्तित करने का तरीका नहीं पता है।

आप Convert.ToString(c.Id) उपयोग करने के बजाय सिर्फ c.Id.ToString() बुलाने की कोशिश कर सकते ...

+0

यह एक ऐतिहासिक डेटाबेस है कि हम प्रयोग कर रहे हैं, जहां a.ReferenzID वास्तव में एक स्ट्रिंग है, कारण यह है कि इसे एक टेबल में एक int में जोड़ा जा सकता है लेकिन एक GUID में। –

+1

धन्यवाद लेकिन Convert.ToString (c.Id) हमें एक ही त्रुटि –

+0

इसका उल्टा परिवर्तित करने का प्रयास करें देता है? इसके बजाए 'नया ग्रिड (ए। रेफरेंसआईडी)' कॉल करें? –

-2

संस्थाओं को LINQ जहाँ तक मैं यह (v1 के लिए) समझ में बहुत आदिम है। अन्य शब्दों में यह नहीं पता कि विस्तार विधि "ToString()" कैसे लेना है और इसके लिए एसक्यूएल उत्पन्न करना है।

LINQ से SQL में, यह SQL उत्पन्न करने से पहले एक्सटेंशन विधि "ToString()" निष्पादित करता है। अंतर यह है कि LINQ से Entities IENumerable के बजाय IQueryable का उपयोग करता है।

लेकिन, मुझे जो याद है उसे कास्टिंग करना चाहिए (क्योंकि कास्टिंग एक डेटा प्रकार है और एसक्यूएल CAST() के बारे में जानता है)।

तो

c.Id.ToString() वास्तव में होना चाहिए (स्ट्रिंग) c.Id

(यह भी सुनिश्चित करें कि यह (स्ट्रिंग) है और नहीं (स्ट्रिंग))।

शुद्ध LINQ के बजाय SQL अभिव्यक्ति उत्पन्न करने के लिए मैं Lambda (Entity Framework में) का उपयोग करने के बारे में कहूंगा।

मन में भी रखें, कि बराबरी की बाईं ओर कास्ट का उपयोग कर एसक्यूएल साइन-इन करें थोड़ा बीमार है :-) प्रदर्शन

+0

देर से DV के लिए खेद है DV: '(स्ट्रिंग) c.Id'" प्रकार को परिवर्तित नहीं कर सकता "int 'to' string 'के साथ संकलित नहीं होगा।" –

+0

जो आपने लिखा है, उससे कोई भी सोच सकता है कि Linq2SQL IQueryable के बजाय IENumerable का उपयोग करता है, जो निश्चित रूप से सत्य नहीं है। –

+1

@ विक्टर ज़िचला: मैंने इसे सत्यापित कर लिया है, आप आसानी से '(स्ट्रिंग)' का उपयोग करके एक ईएफ क्वेरी में स्ट्रिंग में नहीं डाले जा सकते हैं। लेकिन मेरे जवाब पर एक नज़र डालें, मेरे पास अब दो विकल्प हैं (पोस्ट [यहां] (http://stackoverflow.com/a/17447930/1016343)) जो मेरे लिए ठीक काम कर रहे हैं। – Matt

8

यह मेरे लिए कोई मतलब नहीं है क्यों Linq2EF एक उचित SQL में .ToString() अनुवाद नहीं करता है कथन, जैसा कि Linq2SQL करता है, केवल माइक्रोसॉफ्ट देव टीम कारण जानता है कि उन्होंने अभी तक इसे लागू क्यों नहीं किया है। :-(

लेकिन आप अगर आप this link.

का पालन करके इस सुविधा के लिए वोट सौभाग्य से वहाँ भी 2 समाधान उपलब्ध हैं इसे लागू करने के प्राथमिकता बढ़ा सकते हैं, उन दोनों मैं में हाल ही में उपयोग एफई प्रश्नों:


मैं) मुझे क्या मदद की पाने के लिए चारों ओर इस सीमा लिए किया गया था IEnumerable<T>, जहां .ToString() उपलब्ध है

var customersList = (from c in db.Customers 
      select c).ToList(); // converts to IEnumerable<T> ... 
var customersTest = (from c in customersList 
      select new {Id=c.ID.ToString()}); // ... which allows to use .ToString() 

बयान .ToList() धर्मान्तरित: एक सूची में क्वेरी बदल सकता है इसलिए की तरह। नोट कि, आवश्यकताओं के आधार पर, आप .AsEnumerable() का भी उपयोग कर सकते हैं, जिसका लाभ यह है कि स्थगित निष्पादन समर्थित है जो बेहतर है यदि आपके पास एक दूसरे के आधार पर एकाधिक linq प्रश्न हैं या यदि आप विभिन्न पैरामीटर मानों का उपयोग कर रहे हैं (कई इस संकेत के लिए Divega पर धन्यवाद!)।

बाद में आप अगर आप के रूप में आवश्यक आप customersTest की वस्तुओं के लिए और अधिक गुण जोड़ सकते हैं की जरूरत है कि इस प्रश्न के रूप में आप चाहते हैं, उदा .:

var customersTest2 = from c in customersTest     
    select new 
      { 
       Id = c.Id, 
       Addresses = from a in db.Addresses where c.Id == a.ReferenzId select a 
      }; 
बेशक

उपयोग कर सकते हैं। आप ऊपर दी गई क्वेरी को भी अनुकूलित कर सकते हैं, मैंने इस उदाहरण की पठनीयता के लिए केवल 3 चरणों का उपयोग किया है।


द्वितीय) सरल रूपांतरण के लिए, और आप आगे सबक्वेरी में उत्पन्न क्वेरी का पुन: उपयोग करने के लिए है (और यह IQueryable रहने के लिए), System.Data.Objects.SqlClient से SqlFunctions का उपयोग की जरूरत है, वे सही ढंग से एसक्यूएल प्रश्नों में अनुवाद किया जाएगा।

उदाहरण 1: स्ट्रिंग रूपांतरण के लिए सांख्यिक

var customersTest = from c in db.Customers 
    select new { 
     strID=SqlFunctions.StringConvert((double)c.ID) 
    } 

यह मदद करनी चाहिए: दिनांक रूपांतरण

var customersTest = from c in db.Customers 
    select new { 
     strDate=SqlFunctions.DateName("dd", c.EndDate) 
      +"."+SqlFunctions.DateName("mm", c.EndDate) 
      +"."+SqlFunctions.DateName("yyyy", c.EndDate) 
    } 

उदाहरण 2 (आप dateparts जिन्हें आप नीचे देख उपयोग करने के लिए है) आप ज्यादातर स्थितियों में से जहां तारों में रूपांतरण की आवश्यकता होती है।


अद्यतन: आप लिंक मैं अपने जवाब की शुरुआत में आप दे दी अनुसरण किया है, यह याद आ रही सुविधा इस बीच 75 वोट प्राप्त हुआ है और अब implemented by Microsoft in EF 6.1 है (अंत में!)। उन सभी लोगों के लिए जिन्होंने भाग लिया: वोटिंग के लिए धन्यवाद! आपकी आवाज सुनी गई थी।

उदाहरण के लिए:

DECLARE @p0 NVarChar(1000) = '1' 
SELECT [t0].[EmployeeID], [t0].[LastName], [t0].[FirstName], [t0].[Title], 
    [t0].[TitleOfCourtesy], [t0].[BirthDate], [t0].[HireDate], [t0].[Address],[t0].[City], 
    [t0].[Region], [t0].[PostalCode], [t0].[Country], [t0].[HomePhone], [t0].[Extension], 
    [t0].[Photo], [t0].[Notes], [t0].[ReportsTo], [t0].[PhotoPath] 
FROM [Employees] AS [t0] 
WHERE (CONVERT(NVarChar,[t0].[EmployeeID])) = @p0 

अर्थात e.EmployeeID.ToString()(CONVERT(NVarChar,[t0].[EmployeeID])) करने के लिए अनुवाद:

var query = from e in context.Employees where e.EmployeeID.ToString() == "1" select e; 

अब अनुवाद किया जाएगा।

+1

आप हमें ToList() के बजाय AsEnumerable() भी कर सकते हैं। यदि आप स्थगित निष्पादन और अलग-अलग पैरामीटर मानों के साथ क्वेरी को कई बार निष्पादित करने की क्षमता को संरक्षित करना चाहते हैं तो यह एक बेहतर विकल्प हो सकता है। – divega

+0

@ दिवेगा: संकेत के लिए धन्यवाद, मैंने कोशिश की है और यह अच्छी तरह से काम करता है! मैंने अपना जवाब भी अपडेट किया है। – Matt

+0

** एक और संकेत **: यदि आप 'SqlFunctions.StringConvert (...) 'का उपयोग कर रहे हैं, तो आपको' की आवश्यकता होगी।रूपांतरण फ़ंक्शन बनाता है रिक्त स्थान को हटाने के लिए कुछ मामलों में ट्रिम() '। हैरानी की बात है, आप एक प्रश्न में 'SqlFunctions.StringConvert (...) का उपयोग कर सकते हैं। Trim()'! :-) – Matt

6

इकाई की रूपरेखा 6.1 आरटीएम जो अभी जारी किया गया था .ToString का समर्थन()

+0

हां, मैंने संयोग से देखा कि यह इसका समर्थन करता है। लेकिन किसी भी संदर्भ में इसका उल्लेख नहीं है। क्या आप इस मुद्दे के बारे में एक संदर्भ प्रदान कर सकते हैं? –

+0

यह ऊपर दिए गए उत्तर में पोस्ट किया गया है http://data.uservoice.com/forums/72025-entity-framework-feature-suggestions/suggestions/2327346-support-tostring-method-in-linq-to-entities –

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