Je migre certaines choses d'un serveur mysql vers un serveur SQL mais je ne peux pas comprendre comment faire fonctionner ce code:
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();
}
Quand il entre dans la seconde, foreach (var page in pages)
il lance une exception disant:
LINQ to Entities ne reconnaît pas la méthode 'System.String ToString ()', et cette méthode ne peut pas être traduite en une expression de magasin.
Quelqu'un sait pourquoi cela se produit?
Réponses:
Enregistrez simplement la chaîne dans une variable temporaire, puis utilisez-la dans votre expression:
Le problème survient car il
ToString()
n'est pas vraiment exécuté, il est transformé en MethodGroup , puis analysé et traduit en SQL. Puisqu'il n'y a pas d'ToString()
équivalent, l'expression échoue.Remarque:
Assurez-vous également de consulter la réponse d'Alex concernant la
SqlFunctions
classe d'assistance qui a été ajoutée plus tard. Dans de nombreux cas, cela peut éliminer le besoin de la variable temporaire.la source
ToString()
n'en fait pas partie.ExecuteQuery
ou en utilisant Entity SQL avecObjectQuery<T>
Comme d'autres l'ont répondu, cela se rompt car .ToString ne parvient pas à se traduire en SQL pertinent sur le chemin dans la base de données.
Cependant, Microsoft fournit la classe SqlFunctions qui est une collection de méthodes pouvant être utilisées dans des situations comme celle-ci.
Dans ce cas, ce que vous recherchez ici est SqlFunctions.StringConvert :
Bon lorsque la solution avec des variables temporaires n'est pas souhaitable pour quelque raison que ce soit.
Semblable à SqlFunctions, vous avez également les EntityFunctions (avec EF6 obsolète par DbFunctions ) qui fournit un ensemble différent de fonctions qui sont également indépendantes de la source de données (non limitées à SQL par exemple).
la source
Le problème est que vous appelez ToString dans une requête LINQ to Entities. Cela signifie que l'analyseur essaie de convertir l'appel ToString en son équivalent SQL (ce qui n'est pas possible ... d'où l'exception).
Tout ce que vous avez à faire est de déplacer l'appel ToString sur une ligne distincte:
la source
Eu un problème similaire. Résolu le problème en appelant ToList () sur la collection d'entités et en interrogeant la liste. Si la collection est petite, c'est une option.
J'espère que cela t'aides.
la source
Changez-le comme ça et cela devrait fonctionner:
La raison pour laquelle l'exception n'est pas lancée dans la ligne de la requête LINQ est déclarée mais dans la ligne du
foreach
est la fonction d'exécution différée, c'est-à-dire que la requête LINQ n'est pas exécutée tant que vous n'essayez pas d'accéder au résultat. Et cela se produit dans leforeach
et pas plus tôt.la source
Cast table vers
Enumerable
, puis vous appelez les méthodes LINQ avec usingToString()
method inside:Mais attention, lorsque vous appelez des méthodes
AsEnumerable
ou desToList
méthodes, car vous demanderez toutes les données de toutes les entités avant cette méthode. Dans mon cas ci-dessus, je lis toutes lestable_name
lignes par une seule requête.la source
La mise à niveau vers Entity Framework version 6.2.0 a fonctionné pour moi.
J'étais auparavant sur la version 6.0.0.
J'espère que cela t'aides,
la source
Dans MVC, supposez que vous recherchez des enregistrements en fonction de vos besoins ou de vos informations. Cela fonctionne correctement.
la source
Si vous voulez vraiment taper
ToString
dans votre requête, vous pouvez écrire un visiteur d'arborescence d'expression qui réécrit l'appelToString
avec un appel à laStringConvert
fonction appropriée :la source
First
ici est sur les résultats deGetMethods()
quels retoursMethodInfo[]
. AFAIK,MethodInfo[]
n'a pas deFind
méthode, ni de méthode d'extension. Mais je devrais vraiment l'utiliserSingle
car cette méthode est trouvée par réflexion, et il n'y aura pas d'erreur de compilation si la méthode appropriée ne peut pas être résolue.J'ai eu la même erreur dans ce cas:
Après avoir passé beaucoup trop de temps à déboguer, j'ai compris que l'erreur était apparue dans l'expression logique.
La première ligne
search.Contains(log.Id.ToString())
fonctionne bien, mais la dernière ligne qui traite d'un objet DateTime l'a fait échouer lamentablement:Supprimez la ligne problématique et le problème est résolu.
Je ne comprends pas tout à fait pourquoi, mais il semble que ToString () soit une expression LINQ pour les chaînes, mais pas pour les entités. LINQ for Entities traite les requêtes de base de données comme SQL, et SQL n'a aucune notion de ToString (). En tant que tel, nous ne pouvons pas lancer ToString () dans une clause .Where ().
Mais comment fonctionne alors la première ligne? Au lieu de ToString (), SQL a
CAST
etCONVERT
, donc ma meilleure estimation jusqu'à présent est que linq pour les entités l'utilise dans certains cas simples. Les objets DateTime ne sont pas toujours aussi simples ...la source
Transformez simplement la requête LINQ to Entity en requête LINQ to Objects (par exemple, appelez ToArray) chaque fois que vous devez utiliser un appel de méthode dans votre requête LINQ.
la source