GQ08 IV: Linq to Sql bug ?
Un peu de Linq to Sql !
Le fonctionnel est simple, j'aimerais depuis toutes les catégories récupérer une liste d'éléments regroupant le nom de la catégorie ainsi qu'un dictionnaire des produits appartenants à cette catégorie. Ceci afin de pouvoir retrouver rapidement un produit appartenant à une catégorie.
Le code suivant est syntaxiquement correct, il compile même !
Pourtant son exécution est impossible. Quelle est l'erreur ?
var db = new NorthwindDataContext();
var q =
from c in db.Categories
select new { Name = c.CategoryName,
Products = c.Products.ToDictionary(cat => cat.CategoryID) };
foreach (var c in q)
{
if (c.Products.ContainsKey(123))
Console.WriteLine(c.Name + " contient le produit d'id 123");
}
PS: c'est vendredi !! Prenez le temps de répondre et ne laissez pas tout à Matthieu ! :p
Comments
Anonymous
August 08, 2008
PingBack from http://blog.a-foton.ru/2008/08/gq08-iv-linq-to-sql-bug/Anonymous
August 08, 2008
t'es sûr que tu ne t'es pas trompé ? Ton dico, sa clé ça va être le CategoryID. Donc le WriteLine ne me parait pas bon !Anonymous
August 08, 2008
Pour ce qui est de la réponse, je pense qu'il faut utiliser un AsEnumerable()Anonymous
August 08, 2008
Pour ma part, j'aurais fait ça : var db = new DataClasses1DataContext(); var productsDico = db.Categories.AsEnumerable().ToDictionary(cat => cat.CategoryID, cat => cat.Products); var q = db.Categories; foreach (var c in q) { if (productsDico[c.CategoryID].Any(p=>p.ProductID == 123)) Console.WriteLine(c.CategoryName + " contient le produit d'id 123"); } mais je ne pense pas que ce soit ce que tu veux.Anonymous
August 08, 2008
ou plutôt ça (au cas où il y est des catégories sans products : var db = new DataClasses1DataContext(); var productsDico = db.Categories.AsEnumerable().ToDictionary(cat => cat.CategoryID, cat => cat.Products); foreach (var c in db.Categories) { if (productsDico.ContainsKey(c.CategoryID) && productsDico[c.CategoryID].Any(p=>p.ProductID == 123)) Console.WriteLine(c.CategoryName + " contient le produit d'id 123"); }Anonymous
August 08, 2008
Mitsu, continu stp a poster tes quizz pendant que Matthieu déjeune, ce nous laisse un peu plus de temps pour réflechir avant la réponse :)Anonymous
August 08, 2008
J'ai trouvé la solution ! J'ai activé la modération et je limiterai Matthieu à une seule réponse :)Anonymous
August 08, 2008
Mieux ! tu me file les réponses discret et je te ré-invite à prendre une bierre :)Anonymous
August 08, 2008
Mais euh ! Et puis si ton énoncé était plus compréhensible, je n'aurais pas eu besoin de plusieurs réponses :p A propos de réponse, j'ai pas encore vu la tienne (http://blogs.codes-sources.com/matthieu/archive/2008/08/08/comme-mitsu.aspx). Tu le dis si c'est trop compliqué :p Plus sérieusement, c'est ça que tu voulais ?Anonymous
August 09, 2008
The comment has been removedAnonymous
August 09, 2008
Ce que j'attendais était donc bien: var q = from c in db.Categories select c; var q2 = from c in q.AsEnumerable() select new { Name = c.CategoryName, Products = c.Products.ToDictionary(cat => cat.CategoryID) }; q est bien une requête Linq to Sql car la source 'db.Categories' est bien une Table Linq to Sql. Linq to Sql tente donc de convertir l'intégralité de l'expression en SQL. Evidemment le select avec le dictionary n'est pas reconnu à l'exécution et la requête Linq échoue. La question porte donc bien sur l'isolation de la requête. Si vous voulez enchainer des requêtes Linq entre Sql, Xml, objets ou d'autres provider, pensez bien à isoler les requêtes. Pour ceci, deux solutions. Faire un q.ToList() afin de terminer la première requête et démarrer la seconde sur la liste résultante ou utiliser .AsEnumerable() qui 'cassera' la première expression et vous permettra d'être sûr que je reste définit une reqûete Linq to Object.Anonymous
August 10, 2008
"var q = from c in db.Categories select c;" Autant utiliser directement db.Categories.Anonymous
August 11, 2008
Bien sûr Matthieu. Mais là ça permet à tout le monde de bien visualiser une requête simple que l'on peut facilement enrichire d'un 'where', un 'order by' ou autre. Tu comprends ? :)Anonymous
August 12, 2008
C'est pas du jeu ça... je viens de recevoir le flux rss que maintenant ! Qqun sait-il pourquoi il y a tant de décalage ? Ou bien c'est une astuce de Matthieu pour éliminer la concurrence ? :-)