LINQ to Entities no reconoce el método 'System.String ToString()' y este método no se puede traducir a una expresión de tienda
Estoy migrando algunas cosas de un servidor MySQL a un servidor SQL pero no puedo entender cómo hacer que este código funcione:
using (var context = new Context())
{
...
foreach (var item in collection)
{
IQueryable<entity> pages = from p in context.pages
where p.Serial == item.Key.ToString()
select p;
foreach (var page in pages)
{
DataManager.AddPageToDocument(page, item.Value);
}
}
Console.WriteLine("Done!");
Console.Read();
}
Cuando entra en el segundo foreach (var page in pages)
lanza una excepción que dice:
LINQ to Entities no reconoce el método 'System.String ToString()' y este método no se puede traducir a una expresión de tienda.
Alguien sabe por qué pasa esto?
Simplemente guarde la cadena en una variable temporal y luego úsela en su expresión:
var strItem = item.Key.ToString();
IQueryable<entity> pages = from p in context.pages
where p.Serial == strItem
select p;
El problema surge porque ToString()
en realidad no se ejecuta, se convierte en un MethodGroup y luego se analiza y traduce a SQL. Como no hay ToString()
equivalente, la expresión falla.
Nota:
Asegúrese de consultar también la respuesta de Alex sobre la SqlFunctions
clase de ayuda que se agregó más adelante. En muchos casos, puede eliminar la necesidad de la variable temporal.
Como han respondido otros, esto se rompe porque .ToString no se traduce a SQL relevante en el camino hacia la base de datos.
Sin embargo, Microsoft proporciona la clase SqlFunctions , que es una colección de métodos que se pueden utilizar en situaciones como esta.
Para este caso, lo que estás buscando aquí es SqlFunctions.StringConvert :
from p in context.pages
where p.Serial == SqlFunctions.StringConvert((double)item.Key.Id)
select p;
Bueno cuando la solución con variables temporales no es deseable por cualquier motivo.
De manera similar a SqlFunctions, también tiene EntityFunctions (con EF6 obsoleto por DbFunctions ) que proporciona un conjunto diferente de funciones que también son independientes del origen de datos (no limitado a, por ejemplo, SQL).
El problema es que está llamando a ToString en una consulta LINQ to Entities. Eso significa que el analizador está intentando convertir la llamada ToString en su SQL equivalente (lo cual no es posible... de ahí la excepción).
Todo lo que tienes que hacer es mover la llamada ToString a una línea separada:
var keyString = item.Key.ToString();
var pages = from p in context.entities
where p.Serial == keyString
select p;
Transmite la tabla a Enumerable
, luego llamas a los métodos LINQ usando ToString()
el método dentro:
var example = contex.table_name.AsEnumerable()
.Select(x => new {Date = x.date.ToString("M/d/yyyy")...)
Pero tenga cuidado al llamar a métodos AsEnumerable
o ToList
porque solicitará todos los datos de todas las entidades antes de este método. En mi caso anterior, leo todas table_name
las filas mediante una solicitud.
Tuve un problema similar. Lo resolvió llamando a ToList() en la colección de entidades y consultando la lista. Si la colección es pequeña esta es una opción.
IQueryable<entity> pages = context.pages.ToList().Where(p=>p.serial == item.Key.ToString())
Espero que esto ayude.