J'ai deux tables avec lesquelles j'utilise Linq to SQL. Les tables ont une association de 1 à plusieurs. La partie importante du schéma de base de données est la suivante:LINQ To SQL peut-il générer un SQL non valide?
Camera:
Id (int)
SerialNumber (string)
...
CameraCalibration
Id (int)
CameraFk (int)
...
LINQ to SQL que je peux obtenir une liste de tous les calibrations de l'appareil photo pour les caméras avec 10 caractères numéros de série comme suit
var query = from n in db.CameraCalibrations
where n.Camera.SerialNumber.Length == 10
select n
De ma compréhension de LINQ la requête suivante devrait fonctionner également (même si par c'est plutôt comparision brutale ...)
var query = from n in db.CameraCalibrations
where db.Cameras.Where(c => c.Id == n.CameraFk).SingleOrDefault()
.SerialNumber.Length == 10
select n
Cependant quand j'exécute cette deuxième requête contre la Databa Je reçois une exception SQL indiquant "Impossible d'appeler des méthodes sur nvarchar". Quand je regarde le SQL généré, il semble assez clair pourquoi l'exception est générée:
SELECT t0.*
FROM CameraCalibration AS t0
WHERE (
SELECT t1.serialNumber.Length
FROM Camera AS t1
WHERE t1.id = t0.cameraFk
) = 10
Remarquez comment le SQL généré utilise l'expression t1.serialNumber.Length? Je m'attendais à ce que cela soit traduit en LEN (t1.serialNumber), et en effet, avec cette modification, la requête fonctionne.
Est-ce que je fais quelque chose de mal ici? Ou est-ce une erreur dans la façon dont j'ai structuré ma requête et/ou une limitation de LINQ to SQL?
Bien que je puisse facilement restructurer la requête que j'ai utilisée pour démontrer le problème, dans mon scénario réel, cela sera beaucoup plus difficile (en partie en raison de l'implication dynamique de LINQ).
Comment puis-je écrire une requête similaire à la seconde (avec une recherche effectuée dans la clause where) que LINQ to SQL sera heureux d'exécuter?
Assez bizarre - on dirait que vous avez trouvé un bug. Cependant, il est presque toujours préférable d'utiliser une jointure plutôt qu'une sous-requête, alors j'accepte la réponse de Robert Harvey. – Aaronaught