Linq में संस्थाओं को स्ट्रिंग में परिवर्तित करने के साथ समस्या


202
var items = from c in contacts
            select new ListItem
            {
                Value = c.ContactId, //Cannot implicitly convert type 'int' (ContactId) to 'string' (Value).
                Text = c.Name
            };
var items = from c in contacts
            select new ListItem
            {
                Value = c.ContactId.ToString(), //Throws exception: ToString is not supported in linq to entities.
                Text = c.Name
            };

वैसे भी क्या मैं इसे हासिल कर सकता हूं? ध्यान दें, कि VB.NET में कोई समस्या नहीं है पहली स्निपेट का उपयोग करें यह बहुत अच्छा काम करता है, VB लचीला है, im सी # की सख्ती के लिए इस्तेमाल होने में असमर्थ है !!!


2
.ToString () VB में या तो LinqToEF के लिए काम नहीं करता है। IMHO, बेवकूफ की तरह।
स्टिंगजैक

5
@StingyJack, समस्या ELINQ (लाइनक 2 एंटिटीज़) के साथ है, क्योंकि यह आपके कोड को SQL में अनुवाद करती है, और जब यह आंतरिक ToString अनुरोध की बात आती है, तो यह नहीं जानता कि SQL में 'ToString' का अनुवाद कैसे किया जाए। लाइनक 2 ऑब्जेक्ट्स के विपरीत, जब कोई अनुवाद नहीं होता है, और सब कुछ सीएलआर लैम्ब्डा है, तो यह सीधे अनुरोधित वस्तुओं पर किया जाता है।
शमी वेइटहैंडलर

1
मुझे बस इस बात पर चिढ़ है कि वे उस तरह की त्रुटि को संकलित करने की अनुमति देते हैं, और मुझे कारण का एक सादा अंग्रेजी विवरण (sans legal-ese और academia-ese) खोजने के लिए हमेशा के लिए ट्रोल होना पड़ा।
स्टिंगजैक 20

1
आप सही कह रहे हैं, लेकिन वे सही भी हैं, वे सभी सीएलआर और अनुकूलित सीएलआर कार्यक्षमता को एसक्यूएल में अनुवाद करने के लिए नहीं हैं, विशेष रूप से ईएफ :) के शुरुआती शुरुआती संस्करण में नहीं। ToString के बारे में, ब्रायन का जवाब पढ़ें: stackoverflow। com / प्रश्न / १०६६ /६० /…
शम्मी वेइटहैंडलर

महान, लेकिन 3.5, नंबर 4 का उपयोग करने वाले लोगों के बारे में कैसे? फिर क्या?
एकटेरिना

जवाबों:


313

EF v4 के साथ आप उपयोग कर सकते हैं SqlFunctions.StringConvert। इंट के लिए कोई अधिभार नहीं है, इसलिए आपको एक डबल या एक दशमलव में डालने की आवश्यकता है। आपका कोड इस तरह दिखता है:

var items = from c in contacts
            select new ListItem
            {
                Value = SqlFunctions.StringConvert((double)c.ContactId).Trim(),
                Text = c.Name
            };

234
पृथ्वी पर वे int के लिए एक अधिभार क्यों नहीं शामिल करेंगे?
जेरेमी कोएनन

7
@Nestor यह SQL कॉम्पैक्ट के लिए काम नहीं करता है। पाया कि कठिन रास्ता है।
ऑस्टिन

24
परिणाम से पहले व्हाइटस्पेस बचने के लिए आप का उपयोग करना चाहिएSqlFunctions.StringConvert((double)c.ContactId).Trim()
किम Tranjan

2
System.Data.SQLite द मैथोड 'System.String StringConvert (System.Nullable`1 [System.Double]) को Typw' System.Data.Objects। für 'LINQ to Entities' übersetzt werden। ("LINQ to Entities" में अनुवाद नहीं किया जा सकता)
OneWorld

5
बहुत बढ़िया जवाब! कृपया ध्यान दें, आप पर शुरू ईएफ 6 का उपयोग कर रहे हैं, वर्ग दूसरे नामस्थान में स्थानांतरित हो गया है। इसलिए, EF 6 से पहले, आपको शामिल होना चाहिए: "System.Data.Objects.SqlClient" यदि आप EF 6 में अपडेट करते हैं, या बस इस संस्करण का उपयोग कर रहे हैं, तो शामिल करें: "System.Data.Entity.SqlServer" गलत नाम स्थान सहित EF6, कोड ठीक संकलित करेगा, लेकिन रनटाइम त्रुटि को फेंक देगा। मुझे उम्मीद है कि यह नोट कुछ भ्रम से बचने में मदद करता है।
सिंह

12

मैंने क्वेरी से बाहर स्ट्रिंग के पूर्णांक के रूपांतरण को रखकर एक समान समस्या को हल किया। यह किसी ऑब्जेक्ट में क्वेरी डालकर प्राप्त किया जा सकता है।

var items = from c in contacts
            select new 
            {
                Value = c.ContactId,
                Text = c.Name
            };
var itemList = new SelectList();
foreach (var item in items)
{
    itemList.Add(new SelectListItem{ Value = item.ContactId, Text = item.Name });
}

यह इसे हल करने का एक तरीका है, लेकिन ध्यान रखें कि इससे निष्पादन का समय बढ़ जाएगा, अगर आपके पास बड़ी मात्रा में ऑब्जेक्ट हैं, तो यह
फॉर्च ओवरक्लिल

9

LinqToObject का उपयोग करें: संपर्क। AsEnumerable ()

var items = from c in contacts.AsEnumerable()
            select new ListItem
            {
                Value = c.ContactId.ToString(),
                Text = c.Name
            };

धन्यवाद। FYI करें, मैं थोड़ी अलग समस्या को हल करने की कोशिश कर रहा हूं। मैं LINQ का उपयोग संस्थाओं / लंबो के लिए कर रहा हूँ और यह काम करता है। मैं मिलान परिणामों को खोजने के लिए एक Int को String में परिवर्तित करने और "कंटेन्स" का उपयोग करने की कोशिश कर रहा था -> अर्थात db.contacts.AsEnumerable ()। जहाँ (c => c.ContactId.ToString।)। Contains ( searchitem ))। ToList (); ;
एजहोस्ट

9
यदि आप कहते हैं कि AsEnumerableआप बड़े डेटाबेस पर उच्च प्रदर्शन मूल्य का भुगतान करेंगे क्योंकि यह मेमोरी में सब कुछ लाएगा। IEnumerableतुलना में धीमा है IQueryableक्योंकि बाद में डेटाबेस में विशेष रूप से निष्पादित किया जाता है।
कोडआर्टिस्ट

5

SqlFunctions.StringConvert काम करेगा, लेकिन मुझे यह बोझिल लगता है, और ज्यादातर समय, मुझे SQL पर स्ट्रिंग रूपांतरण करने की वास्तविक आवश्यकता नहीं है।

अगर मैं स्ट्रिंग मैनिपुलेशन करना चाहता हूं, तो पहले linq-to-इकाइयों में क्वेरी निष्पादित करता हूं, फिर linq-to-ऑब्जेक्ट्स में स्टिंग्स में हेरफेर करता हूं। इस उदाहरण में, मैं एक संपर्क का पूरा नाम, और ContactLocationKey युक्त डेटा का एक सेट प्राप्त करना चाहता हूं, जो दो पूर्णांक कॉलम (ContactID और LocationID) का स्ट्रिंग संयोजन है।

// perform the linq-to-entities query, query execution is triggered by ToArray()
var data =
   (from c in Context.Contacts
   select new {
       c.ContactID,
       c.FullName,
       c.LocationID
   }).ToArray();

// at this point, the database has been called and we are working in
// linq-to-objects where ToString() is supported
// Key2 is an extra example that wouldn't work in linq-to-entities
var data2 =
   (from c in data
    select new {
       c.FullName,
       ContactLocationKey = c.ContactID.ToString() + "." + c.LocationID.ToString(),
       Key2 = string.Join(".", c.ContactID.ToString(), c.LocationID.ToString())
    }).ToArray();

अब, मैं अनुदान देता हूं कि दो अनाम चयनों को लिखने के लिए बोझिल होना पड़ता है, लेकिन मैं तर्क दूंगा कि जिस सुविधा से आप स्ट्रिंग (और अन्य) कार्य कर सकते हैं, वह L2E में समर्थित नहीं है। यह भी ध्यान रखें कि इस पद्धति का उपयोग करके संभवतः एक प्रदर्शन जुर्माना है।


4
public static IEnumerable<SelectListItem> GetCustomerList()
        {
            using (SiteDataContext db = new SiteDataContext())
            {
                var list = from l in db.Customers.AsEnumerable()
                           orderby l.CompanyName
                           select new SelectListItem { Value = l.CustomerID.ToString(), Text = l.CompanyName };

                return list.ToList();
            }
        }

क्या आपने इसका परीक्षण किया और यह काम करता है? इस उत्तर को पहले पढ़ें ।
शिमी वेइटहैंडलर

हां, मैं पहले से ही इसका इस्तेमाल कर रहा हूं। यह MVC3, EF4, CTP5, SQL CE4 के लिए काम करता है।
नेस्टर

यह बॉक्सिंग से दोगुना और स्ट्रिंगरकोवर्ट का उपयोग करने से अधिक सुरुचिपूर्ण लगता है।
CmdrTallen

9
लेकिन इस मामले में आप डेटाबेस से सभी डेटा प्राप्त करेंगे तो मान लीजिए कि आप इस सूची पर पहले कुछ फ़िल्टर करना चाहते हैं return list.ToList();!!
वाहिद बितर

4
जब आप SqlFunctions का उपयोग नहीं कर सकते हैं तो आपके पास इसके अलावा कई अन्य विकल्प नहीं हैं। हालाँकि, मैंने इसका उपयोग अपनी क्वेरी के लिए किया होगा return (from l in db.Customers orderby l.CompanyName select new {Id=l.CustomerID, Name=l.CompanyName}).AsEnumerable().Select(c=> new SelectListItem{Value=c.Id.ToString(), Text = c.Name}).ToList();:। इस तरह से करने से केवल db (सभी ग्राहक गुणों के बजाय) से आईडी / नाम मिलता है और db पर अधिक कुशल सूचकांक का उपयोग करके क्रमबद्ध करता है।
ब्रायन कॉउटन

3
var selectList = db.NewsClasses.ToList<NewsClass>().Select(a => new SelectListItem({
    Text = a.ClassName,
    Value = a.ClassId.ToString()
});

सबसे पहले, ऑब्जेक्ट में कनवर्ट करें, फिर स्ट्रींग () सही होगा।


3

ब्रायन कॉउटन का जवाब बहुत अच्छा है! बस थोड़ा सा अपडेट, EF 6 के लिए, क्लास दूसरे नामस्थान में स्थानांतरित हो गई। इसलिए, ईएफ 6 से पहले, आपको शामिल करना चाहिए:

System.Data.Objects.SqlClient

यदि आप EF 6 में अपडेट करते हैं, या बस इस संस्करण का उपयोग कर रहे हैं, तो शामिल करें:

System.Data.Entity.SqlServer

EF6 के साथ गलत नाम स्थान को शामिल करके, कोड केवल ठीक संकलित करेगा लेकिन रनटाइम त्रुटि को फेंक देगा। मुझे उम्मीद है कि यह नोट कुछ भ्रम से बचने में मदद करता है।


मेरा कहना है कि आपका उत्तर उत्कृष्ट है। मैंने EF6 में अपग्रेड किया और SqlFunctions के लिए हर जगह देख रहा हूं। आपके उत्तर ने मुझे सही दिशा में इशारा किया। मैं सिर्फ इतना जोड़ता हूं कि आपको EntityFramework.SqlServer के संदर्भ में भी आवश्यकता होगी (आपके पास केवल EntityFramework का संदर्भ हो सकता है)।
मेटलजिक

2

मैं इसी समस्या में भाग गया जब मैं अपने MVC 2 ऐप को MVC 3 में परिवर्तित कर रहा था और इस समस्या का एक और (स्वच्छ) समाधान देने के लिए मैं जो करना चाहता था, पोस्ट करना चाहता हूं ...

IEnumerable<SelectListItem> producers = new SelectList(Services.GetProducers(),
    "ID", "Name", model.ProducerID);

GetProducers () केवल निर्माता का एक इकाई संग्रह लौटाता है। PS SqlFunctions.StringConvert ने मेरे लिए काम नहीं किया।


2

यदि आपका "संपर्क" सामान्य सूची के रूप में कार्य कर रहा है, तो मुझे उम्मीद है कि निम्नलिखित कोड अच्छी तरह से काम करता है।

var items = contact.Distinct().OrderBy(c => c.Name)
                              .Select( c => new ListItem
                              {
                                Value = c.ContactId.ToString(),
                                Text = c.Name
                              });

धन्यवाद।


2

एक और उपाय:

c.ContactId + ""

बस खाली स्ट्रिंग जोड़ें और इसे स्ट्रिंग में परिवर्तित किया जाएगा।


लौटी हुई त्रुटि: System.NotSupportedException: 'System.Int64' टाइप करने के लिए 'System.Object' टाइप करने में असमर्थ। LINQ to Entities केवल EDM आदिम या गणना प्रकार का समर्थन करता है।
QMaster

1

MySql का उपयोग करते हुए, SqlFunctions.StringConvertमेरे लिए काम नहीं किया। चूंकि मैं SelectListItemअपनी परियोजना में 20+ स्थानों का उपयोग करता हूं, इसलिए मैं एक समाधान चाहता था जो 20+ LINQ स्टेटमेंट के बिना काम करे। मेरा समाधान उप-वर्ग का थाSelectedListItemपूर्णांक सेट्टर प्रदान करने के लिए में , जो LINQ से दूर रूपांतरण टाइप करता है। जाहिर है, इस समाधान को सामान्य करना मुश्किल है, लेकिन मेरी विशिष्ट परियोजना के लिए काफी मददगार था।

उपयोग करने के लिए, निम्न प्रकार बनाएं और अपनी LINQ क्वेरी के स्थान पर SelectedListItemउपयोग करें और मान के स्थान पर IntValue का उपयोग करें।

public class BtoSelectedListItem : SelectListItem
{
    public int IntValue
    {
        get { return string.IsNullOrEmpty(Value) ? 0 : int.Parse(Value); }
        set { Value = value.ToString(); }
    }
}

1

यदि आप इकाई ढांचे का उपयोग करते हैं और आप एकमात्र इंट को स्वीकार्य बनाना चाहते हैं तो आप इसे linq क्वेरी में उपयोग कर सकते हैं

var items = from c in contacts
        select new ListItem
        {
            Value = (int)ContractId 
            Text = c.Name
        };

यह काम करेगा क्योंकि (int) आपके मान को int में डालेगा ताकि आपको int के लिए किसी भी रूपांतरण की आवश्यकता न हो और आपको मनचाहा परिणाम मिल सके।

यह मेरे लिए मेरी परियोजना में काम करता है मुझे लगता है कि यह आपके लिए उपयोगी होगा


-2

मेरी समझ यह है कि आपको अपने मॉडल को "विस्तारित" करने के लिए एक आंशिक वर्ग बनाना होगा और एक ऐसी संपत्ति को जोड़ना होगा जो आसानी से हो जो कक्षा के बाकी गुणों का उपयोग कर सके।

public partial class Contact{

   public string ContactIdString
   {
      get{ 
            return this.ContactId.ToString();
      }
   } 
}

फिर

var items = from c in contacts
select new ListItem
{
    Value = c.ContactIdString, 
    Text = c.Name
};

नहीं, आप LINQ से Entities (.NET 3.5) में कस्टम गुणों का उपयोग नहीं कर सकते।
क्रेग स्टंट ज़ूल

1
मैंने इसका परीक्षण नहीं किया, लेकिन यह काम भी नहीं करेगा। चूंकि यह एक टेबल फील्ड प्रॉपर्टी नहीं है। मैं पहले ToArray () के साथ कर सकता था फिर वस्तुओं पर लाइनकिंग लेकिन मैं DB को क्वेरी करना चाहता हूं। मुझे लगता है कि यह करने में सक्षम नहीं होगा। मैंने अपनी खुद की ListItem बनाई है जो एक इंट फील्ड लेती है। वह मेरे लिए बेहतर काम करता है।
शिमी वेइटहैंडलर

-2
var items = from c in contacts
select new ListItem
{
    Value = String.Concat(c.ContactId), //This Works in Linq to Entity!
    Text = c.Name
};

मैंने पाया कि SqlFunctions.StringConvert((double)c.Age)मेरे लिए काम नहीं किया या तो क्षेत्र प्रकार का हैNullable<Int32>

इसे खोजने के लिए पिछले कुछ दिनों के परीक्षण और त्रुटि पर मुझे बहुत खोजा।

मुझे आशा है कि यह कुछ कोडर्स को वहां से निकालने में मदद करता है।


1
मेरे लिए काम नहीं करता है। यह अपवाद को फेंकता है " ... System.String Concat(System.Object)एक स्टोर अभिव्यक्ति में अनुवादित नहीं किया जा सकता ... "।
सुलामा

1
मेरे लिए भी काम नहीं करता है। मुझे "System.NotSupportedException: LINQ to Entities 'विधि' System.String Concat (System.Object) 'विधि की पहचान नहीं है, और यह विधि किसी स्टोर अभिव्यक्ति में अनुवादित नहीं की जा सकती है।"
19

1
काम नहीं करता है - इस तर्क को बदल दें [NotSupportedException: LINQ to Entities विधि 'System.String Concat (System.Object)' विधि को नहीं पहचानता है, और इस पद्धति को स्टोर एक्सप्रेशन में अनुवादित नहीं किया जा सकता है]
फिलिप मुनिन

-6

क्या आप इसे आजमा सकते है:

var items = from c in contacts
        select new ListItem
        {
            Value = Convert.ToString(c.ContactId), 
            Text = c.Name
        };

उपरोक्त कोड काम नहीं करेगा क्योंकि यह एक त्रुटि कहेगा कि "LINQ से लेकर एंटिटीज़ 'पद्धति को नहीं पहचानता है' System.String ToString (Int32) विधि, और इस विधि को स्टोर एक्सप्रेशन में अनुवादित नहीं किया जा सकता है।"
GK
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.