11
votes

LINQ "ne pouvait pas traduire l'expression ... en SQL et ne pouvait pas le traiter comme une expression locale."

J'ai commencé avec cette question , que j'ai une sorte de réponse Il , et maintenant je demande à la question la plus fondamentale ici. J'ai simplifié la requête à ce sujet: xxx

tel.formattedNumber est une propriété qui combine le numéro numéro et extension champs dans une chaîne soigneusement formatée. Et voici l'erreur qui obtient des résultats: xxx

si je modifie la référence ci-dessus de formatatedNumber à juste uni numéro , tout fonctionne bien.

mais je veux que le nombre formaté soit bien afficher dans ma liste. Que recommandez-vous comme le meilleur moyen le plus propre et le plus propre?


0 commentaires

3 Réponses :


13
votes

Vous pouvez utiliser asenumerable sur l'entité, mais cela le forcerait à ramener toutes les colonnes (même s'il n'est pas utilisé); Peut-être plutôt quelque chose comme: xxx

est-ce que est une méthode qui en prend les deux et les fusionne, probablement réutilisée à partir de votre autre code (propriété).

avec LINQ-TO-SQL, une autre option consiste à exposer un UDF sur le contexte de données qui effectue la mise en forme de la base de données; un exemple légèrement différent: xxx

(qui fera le travail dans la base de données; que ce soit une bonne idée ;-p)


0 commentaires


3
votes

Le moyen propre consiste à énoncer les champs que vous souhaitez réellement dans l'expression, mettez-les dans vos objets de niveau moyenne, puis utilisez toutes les fonctions auxiliaires pour les modifier ce dernier.

Je ne sais pas si vous réalisez qu'une classe représentant la table SQL pour Linq est une classe DTO - elle définit la grammaire utilisée par Linq-SQL Translator. Injecter une propriété dans une DTO qui n'est pas mappée sur la table SQL n'est même pas prise en charge - ce qui signifie que le traducteur peut tirer à volonté. Les attributs définissent la grammaire et tout ce qui n'est pas défini par eux n'existe pas pour l'expression traductrice.

Les entités nommées dans la clause de gamme ne sont pas des objets - ce ne sont que des symboles utilisés pour aider à orthographier des champs de table réels qui seront récupérés. Un champ non nommé explicitement dans Select est un champ non récupéré - au moins c'est l'objectif du traducteur, il peut être nécessaire de laisser quelques-uns à travers. Par exemple, si ce nom Ent.formattedName n'est pas déclaré, c'est un glissement et peut exploser ce dernier.

Donc, cette propriété de formatée injectée dans la classe DTO n'existe même pas dans la grammaire. Ce n'est pas un "champ calculé" - ce terme est strictement pour les définitions de table SQL et si vous en avez eu une ce qui serait dans la grammaire de DTO. Notez que l'erreur a dit très précisément «expression locale» - une portée très limitée.

Vous pouvez essayer de le tromper par une expression lambda imbriquée appeler une fonction statique sur l'ensemble du "Tel", qui pourrait tirer parti de l'ensemble du record - ou de lancer une autre exception.

Autre Linq-S, qui ne sont pas des traducteurs, peuvent avoir des règles détendues. LINQ-SQL doit être très strict ou très lent et il est déjà assez lent: -)


0 commentaires