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?
Respuestas:
Simplemente guarde la cadena en una variable temporal y luego úsela en su expresión:
El problema surge porque
ToString()
no se ejecuta realmente, se convierte en un MethodGroup y luego se analiza y traduce a SQL. Como no hayToString()
equivalente, la expresión falla.Nota:
Asegúrese de consultar también la respuesta de Alex con respecto a la
SqlFunctions
clase auxiliar que se agregó más tarde. En muchos casos, puede eliminar la necesidad de la variable temporal.fuente
ToString()
no es uno de ellos.ExecuteQuery
o utilizando Entity SQL conObjectQuery<T>
Como otros han respondido, esto se rompe porque .ToString no puede traducirse 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 usar en situaciones como esta.
Para este caso, lo que está buscando aquí es SqlFunctions.StringConvert :
Bueno cuando la solución con variables temporales no es deseable por alguna razón.
Similar a SqlFunctions, también tiene las 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).
fuente
El problema es que está llamando a ToString en una consulta LINQ to Entities. Eso significa que el analizador está tratando de convertir la llamada ToString en su SQL equivalente (que no es posible ... de ahí la excepción).
Todo lo que tiene que hacer es mover la llamada ToString a una línea separada:
fuente
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.
Espero que esto ayude.
fuente
Cámbialo así y debería funcionar:
La razón por la cual la excepción no se arroja en la línea se declara la consulta LINQ sino en la línea de la
foreach
función de ejecución diferida, es decir, la consulta LINQ no se ejecuta hasta que intente acceder al resultado. Y esto sucede en elforeach
y no antes.fuente
Transmitir tabla a
Enumerable
, luego llama a los métodos LINQ con el uso delToString()
método dentro:Pero tenga cuidado, cuando llame
AsEnumerable
oToList
métodos porque solicitará todos los datos de todas las entidades antes de este método. En mi caso anterior, leí todas lastable_name
filas por una solicitud.fuente
La actualización a Entity Framework Versión 6.2.0 funcionó para mí.
Anteriormente estaba en la versión 6.0.0.
Espero que esto ayude,
fuente
En MVC, suponga que está buscando registros según sus requisitos o información. Funciona correctamente
fuente
Si realmente desea escribir
ToString
dentro de su consulta, puede escribir un visitante del árbol de expresiones que reescriba la llamadaToString
con una llamada a laStringConvert
función adecuada :fuente
First
aquí está en los resultados de losGetMethods()
cuales regresaMethodInfo[]
. AFAIK,MethodInfo[]
no tiene unFind
método, ni existe tal método de extensión. Pero realmente debería usarloSingle
porque este método se encuentra a través de la reflexión, y no habrá un error en tiempo de compilación si no se puede resolver el método apropiado.Recibí el mismo error en este caso:
Después de pasar demasiado tiempo depurando, descubrí que el error apareció en la expresión lógica.
La primera línea
search.Contains(log.Id.ToString())
funciona bien, pero la última línea que trata con un objeto DateTime hizo que fallara miserablemente:Elimine la línea problemática y el problema resuelto.
No entiendo completamente por qué, pero parece que ToString () es una expresión LINQ para cadenas, pero no para Entidades. LINQ for Entities trata consultas de bases de datos como SQL, y SQL no tiene noción de ToString (). Como tal, no podemos lanzar ToString () en una cláusula .Where ().
¿Pero cómo funciona la primera línea? En lugar de ToString (), SQL tiene
CAST
yCONVERT
, así que mi mejor suposición hasta ahora es que linq para entidades usa eso en algunos casos simples. Los objetos DateTime no siempre son tan simples ...fuente
Simplemente convierta la consulta LINQ to Entity en una consulta LINQ to Objects (por ejemplo, llame a ToArray) cada vez que necesite usar una llamada a un método en su consulta LINQ.
fuente