Estou migrando algumas coisas de um servidor mysql para um servidor sql, mas não consigo descobrir como fazer esse código funcionar:
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();
}
Quando entra no segundo foreach (var page in pages)
, lança uma exceção dizendo:
O LINQ to Entities não reconhece o método 'System.String ToString ()' e esse método não pode ser convertido em uma expressão de armazenamento.
Alguém sabe por que isso acontece?
Respostas:
Apenas salve a string em uma variável temporária e use-a na sua expressão:
O problema surge porque, na
ToString()
verdade, não é executado, ele é transformado em um MethodGroup e, em seguida, analisado e traduzido para SQL. Como não háToString()
equivalente, a expressão falha.Nota:
Verifique também a resposta de Alex sobre a
SqlFunctions
classe auxiliar que foi adicionada mais tarde. Em muitos casos, pode eliminar a necessidade da variável temporária.fonte
ToString()
não é um deles.ExecuteQuery
ou usando Entity SQL comObjectQuery<T>
Como outros responderam, isso é interrompido porque .ToString falha ao converter para SQL relevante no caminho para o banco de dados.
No entanto, a Microsoft fornece a classe SqlFunctions que é uma coleção de métodos que podem ser usados em situações como essa.
Para este caso, o que você está procurando aqui é SqlFunctions.StringConvert :
Bom quando a solução com variáveis temporárias não é desejável por qualquer motivo.
Semelhante ao SqlFunctions, você também tem o EntityFunctions (com EF6 obsoleto pelo DbFunctions ) que fornece um conjunto diferente de funções que também são independentes de fonte de dados (não limitadas a, por exemplo, SQL).
fonte
O problema é que você está chamando o ToString em uma consulta LINQ to Entities. Isso significa que o analisador está tentando converter a chamada ToString em seu SQL equivalente (o que não é possível ... daí a exceção).
Tudo o que você precisa fazer é mover a chamada ToString para uma linha separada:
fonte
Teve um problema semelhante. Resolvido, chamando ToList () na coleção de entidades e consultando a lista. Se a coleção for pequena, essa é uma opção.
Espero que isto ajude.
fonte
Altere assim e deve funcionar:
O motivo pelo qual a exceção não é lançada na linha em que a consulta LINQ é declarada, mas na linha do
foreach
é o recurso de execução adiada, ou seja, a consulta LINQ não é executada até que você tente acessar o resultado. E isso acontece noforeach
e não antes.fonte
Transmitir tabela para
Enumerable
, então você chama métodos LINQ usando oToString()
método dentro:Mas tenha cuidado ao chamar métodos
AsEnumerable
ouToList
porque você solicitará todos os dados de todas as entidades antes desse método. No meu caso acima, li todas astable_name
linhas por uma solicitação.fonte
A atualização para o Entity Framework Versão 6.2.0 funcionou para mim.
Eu estava anteriormente na versão 6.0.0.
Espero que isto ajude,
fonte
No MVC, suponha que você esteja pesquisando registros com base em seus requisitos ou informações. Está funcionando corretamente.
fonte
Se você realmente deseja digitar
ToString
dentro de sua consulta, pode escrever um visitante da árvore de expressão que reescreva a chamadaToString
com uma chamada para aStringConvert
função apropriada :fonte
First
aqui é nos resultados dosGetMethods()
quais retornaMethodInfo[]
. AFAIK,MethodInfo[]
não possui umFind
método, nem existe um método de extensão. Mas eu realmente devo usarSingle
porque esse método está sendo encontrado via reflexão e não haverá um erro em tempo de compilação se o método apropriado não puder ser resolvido.Eu recebi o mesmo erro neste caso:
Depois de passar muito tempo depurando, descobri que o erro aparecia na expressão lógica.
A primeira linha
search.Contains(log.Id.ToString())
funciona bem, mas a última linha que lida com um objeto DateTime fez com que falhasse miseravelmente:Remova a linha problemática e o problema resolvido.
Eu não entendo completamente o porquê, mas parece que ToString () é uma expressão LINQ para strings, mas não para Entidades. O LINQ for Entities lida com consultas de banco de dados como SQL e SQL não tem noção de ToString (). Como tal, não podemos lançar ToString () em uma cláusula .Where ().
Mas como funciona a primeira linha? Em vez de ToString (), o SQL tem
CAST
eCONVERT
, portanto, o meu melhor palpite até agora é que o linq for entity use isso em alguns casos simples. Os objetos DateTime nem sempre são tão simples ...fonte
Basta transformar a consulta LINQ to Entity em uma consulta LINQ to Objects (por exemplo, chamar ToArray) sempre que precisar usar uma chamada de método na sua consulta LINQ.
fonte