Perché LINQ to Entities non riconosce il metodo ‘System.String ToString ()?

Ottenere errori nell’applicazione web MVC3. LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression.

quando provo a recuperare i valori usando EF dalla query:

 public class DataRepository { public mydataEntities1 dbContext = new mydataEntities1(); public List GetPricingSecurityID() { var pricingSecurityID = (from m in dbContext.Reporting_DailyNAV_Pricing select new SelectListItem { Text = m.PricingSecurityID.ToString(), Value = m.PricingSecurityID.ToString() }); return pricingSecurityID.ToList(); } } 

Questo non può essere convertito in SQL. Immagino, in teoria, potrebbe, ma non è implementato.

Hai solo bisogno di eseguire la tua proiezione dopo aver ottenuto i risultati:

 var pricingSecurityID = (from m in dbContext.Reporting_DailyNAV_Pricing select m.PricingSecurityID).AsEnumerable() .Select(x => new SelectListItem{ Text = x.ToString(), Value = x.ToString() }); 

Se è già una stringa, perché ti preoccupi di chiamare ToString in primo luogo? Sospetto che una traduzione non sia stata inclusa in LINQ alle Entità perché è inutile. Modifica la tua clausola di selezione su:

 select new SelectListItem { Text = m.PricingSecurityID, Value = m.PricingSecurityID } 

Se hai davvero bisogno di fare qualcosa che non è supportato da LINQ alle quadro, usa AsEnumerable per passare da una query di database a in-process:

 public List GetPricingSecurityID() { return dbContext.Reporting_DailyNAV_Pricing .Select(m => m.PricingSecurityID) .AsEnumerable() // Rest of query is local // Add calls to ToString() if you really need them... .Select(id => new SelectListItem { Text = id, Value = id }) .ToList(); } 

Sono d’accordo anche con le obiezioni di Jason, btw. Faresti meglio a restituire un List che viene visualizzato altrove.

Si noti inoltre che se si sta solo utilizzando una singola clausola select o solo una clausola where, le espressioni di query non aggiungono molto – chiamando i metodi di estensione LINQ si può finire con meno clutter, in particolare se si desidera chiamare metodi che non sono supportati nelle espressioni di query (come ToList ).

Perché sta provando a convertirlo in SQL, e non può. Abbandona la chiamata a ToString e fai una proiezione prima di tornare al chiamante. Quindi, sostituisci la tua clausola di select con

 select m.PricingSecurityID 

e poi dire

 return pricingSecurityID .AsEnumerable() .Select(x => x.ToString()) .Select(x => new SelectListItem { Text = x, Value = x }) .ToList(); 

Inoltre, noto che stai mescolando preoccupazioni relative all’interfaccia utente e problemi di query dei dati. Questa è generalmente una ctriggers pratica. In realtà, dovresti solo restituire l’elenco degli ID e lasciare che la parte relativa all’interfaccia utente del tuo codice si preoccupi di inquadrarla nella forma corretta.

Cosa ne pensi di questo. In questo esempio, sia il campo VDN nel campo db che il campo Abilità sono numeri interi. Sto cercando le corrispondenze da entrambi i campi quindi ho 2 confronti.

Includi questo:

 using System.Data.Objects.SqlClient; // needed to convert numbers to strings for linq 

Quando si confrontano i numeri, fare questo:

  // Search Code if (!String.IsNullOrEmpty(searchString)) { depts = depts.Where(d => SqlFunctions.StringConvert((double)d.VDN).Contains(searchString.ToUpper()) || SqlFunctions.StringConvert((double)d.Skill).Contains(searchString.ToUpper())); } // End Search Code 

Workie.

Purtroppo EF non sa come convertire .ToString () È necessario utilizzare la funzione incorporata SqlFunctions.StringConvert: http://msdn.microsoft.com/en-us/library/dd466292.aspx Inoltre non c’è sovraccarico per int, quindi è necessario typecast to double 🙁

 var vendors = from v in Vendors select new { Code = SqlFunctions.StringConvert((double)v.VendorId) }; 

Capisco che questa domanda abbia una risposta e sono d’accordo che usare AsEnumerable() è la strada da percorrere. Tuttavia, vorrei evidenziare uno scenario comune che di solito mi imbatte in cui AsEnumerable() viene utilizzato in modo inefficiente per risolvere questo errore.

Da una query integrata in linguaggio .NET per dati relazionali

L’operatore AsEnumerable (), a differenza di ToList () e ToArray (), non causa l’esecuzione della query. È ancora rinviato. L’operatore AsEnumerable () modifica semplicemente la tipizzazione statica della query, trasformando un IQueryable in un object IEnumerable, ingannando il compilatore nel trattare il resto della query come eseguito localmente.

Riferimenti

  1. Sto fraintendendo LINQ con SQL. Asumerico ()?
  2. Comprensione .AsEnumerable () in LINQ to SQL

Modo inefficiente

 IEnumerable inefficientEnumerable = (from a in db.Invoices where a.Practice_Key == practiceKey.FirstOrDefault() select a ).AsEnumerable(). Select(x => new InvoiceDTO { InvoiceID = x.InvoiceID, PracticeShortName = x.Dim_Practice.Short_Name, InvoiceDate = x.InvoiceDate, InvoiceTotal = x.InvoiceAmount, IsApproved = x.IsApproved, InvoiceStatus = ( x.IsApproved == null ? "Pending" : x.IsApproved == true ? "Approved" : x.IsApproved == false ? "Rejected" : "Unknown" ), InvoicePeriodStartDateText = x.InvoicePeriodStart.ToShortDateString(), InvoicePeriodEndDateText = x.InvoicePeriodEnd.ToShortDateString(), InvoicePeriodStartDate = x.InvoicePeriodStart, InvoicePeriodEndDate = x.InvoicePeriodEnd } ); invoices = inefficientEnumerable.ToList(); 

Qui l’ AsEnumerable viene utilizzato per l’intera tabella. Tutte le colonne vengono selezionate anche se non sono necessarie.

Modo migliore

  IQueryable invoicesQuery = (from a in db.Invoices where a.Practice_Key == practiceKey.FirstOrDefault() select new InvoiceDTO { InvoiceID = a.InvoiceID, PracticeShortName = a.Dim_Practice.Short_Name, InvoiceDate = a.InvoiceDate, InvoiceTotal = a.InvoiceAmount, IsApproved = a.IsApproved, InvoiceStatus = ( a.IsApproved == null ? "Pending" : a.IsApproved == true ? "Approved" : a.IsApproved == false ? "Rejected" :"Unknown" ), InvoicePeriodStartDate = a.InvoicePeriodStart, InvoicePeriodEndDate = a.InvoicePeriodEnd }); IEnumerable betterEnumerable = invoicesQuery.AsEnumerable(). Select(x => new InvoiceDTO { InvoiceID = x.InvoiceID, PracticeShortName = x.PracticeShortName, InvoiceDate = x.InvoiceDate, InvoiceTotal = x.InvoiceTotal, IsApproved = x.IsApproved, InvoiceStatus = x.InvoiceStatus, InvoicePeriodStartDateText = x.InvoicePeriodStartDate.ToShortDateString(), InvoicePeriodEndDateText = x.InvoicePeriodEndDate.ToShortDateString(), InvoicePeriodStartDate = x.InvoicePeriodStartDate, InvoicePeriodEndDate = x.InvoicePeriodEndDate } ); 
 return dbContext.Reporting_DailyNAV_Pricing.AsEnumerable().Select(x => new SelectListItem { Text = x.PricingSecurityID.ToString(), Value = x.PricingSecurityID.ToString() }).ToList();