avril
2010
Dernièrement, j’ai utilisé LINQ To SQL pour réaliser un UNION sur deux requêtes. Certains champs d’une des deux requêtes avaient volontairement pour valeur string.Empty. Seulement, lors de l’exécution cette exception est apparue :
“All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists.”.
Vous me direz la résolution du problème est simple, il suffit de vérifier qu’il y a bien le même nombre de champs sélectionnés dans les deux SELECT de la requête. Seulement c’est déjà le cas ! Comment expliquer cela alors ? C’est en fait simple : LINQ To SQL génère une requête SQL à partir de la Query déclarée dans le code. Lors de la génération, LINQ procède à certaines optimisations dont le retrait des valeurs utilisées plusieurs fois dans les SELECT (ou bien des champs présents plusieurs fois). Un petit exemple sera plus parlant :
var a = (from t in dc.Table
select new {
Element1 = t.Champ1,
Element2 = t.Champ2,
}
).Union(from t in dc.Table
select new {
Element1 = t.Champ1,
Element2 = t.Champ1, // notez la répétition
});
Génèrera le SQL suivant :
SELECT [t2].[Champ1] AS [Element1], [t2].[Champ2] AS [Element2]
FROM (
SELECT [t0].[Champ1], [t0].[Champ2]
FROM [dbo].[Table] AS [t0]
UNION
SELECT [t1].[Champ1] – Notez l’absence du deuxième Champ1
FROM [dbo].[Table] AS [t1]
) AS [t2]
var a = (from t in dc.Table
select new {
Element1 = t.Champ1,
Element2 = t.Champ2,
Element3 = t.Champ3,
}
).Union(from t in dc.Table
select new {
Element1 = t.Champ1,
Element2 = string.Empty,
Element3 = string.Empty,
});
Génèrera le SQL suivant :
SELECT [t2].[Champ1] AS [Element1], [t2].[Champ2] AS [Element2], [t2].[Champ3] AS [Element3]
FROM (
SELECT [t0].[Champ1], [t0].[Champ2], [t0].[Champ3]
FROM [dbo].[Table] AS [t0]
UNION
SELECT [t1].[Champ1], @p0 AS [value]
FROM [dbo].[Table] AS [t1]
) AS [t2]
var a = (from t in dc.Table
select new {
Element1 = t.Champ1,
Element2 = t.Champ2,
Element3 = t.Champ3,
}
).Union(from t in dc.Table
let defaultString = default(string)
select new {
Element1 = t.Champ1,
Element2 = string.Empty,
Element3 = defaultString,
});
PS : Au passage, je vous invite à consulter ce billet pour savoir comment visualiser dans la fenêtre Output de Visual Studio le code SQL généré par LINQ lors de l’exécution : http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11
Articles récents
- [ASP.NET MVC] De l’open source à tous les étages : Microsoft accélère le virage amorcé depuis MVC 1
- [ASP.NET] Introduction MVC 4 – Part 6 : Introduction à la notion de modèle et de validation par l’exemple
- [ASP.NET] Introduction MVC 4 – Part 5 : Introduction à la notion de contrôleur et de vue par l’exemple
- [ASP.NET] Introduction MVC 4 – Part 4 : Installation de l’environnement de développement
- [ASP.NET] Introduction MVC 4 – Part 3 : MVC c’est quoi ? Quels avantages ?
Commentaires récents
- [ASP.NET MVC] Les vidéos de la MvcConf disponibles ! dans
- [ASP.NET MVC] Retrouvez Scott Guthrie, Scott Hanselman et Phil Haack à la MvcConf dans
- [Visual Studio 2010] Ajouter une commande pour obtenir le PublicKeyToken d’un assembly dans
- [PDC 2010] Premiers retours dans
- [PDC 2010] Premiers retours dans