2010-02-04 4 views
3

SQL et Self connexes Nous avons le modèle de test suivant dans le fichier dbml:LINQ au tableau

Model http://www.freeimagehosting.net/uploads/a86582498a.gif

Pour le cas de test il y a 4 enregistrements de la table, 1 parents, 3 enfants. Nous recherchons les frères et soeurs d'un enregistrement spécifique, y compris le dossier spécifique.

using (var db = new TestDataContext()) 
{ 
    var query = 
     from f in db.Foos 
     where f.Name == "Two" 
     select f.Foo1.Foos;    // get the record's parent's children 

    var foos = query.SelectMany(f => f); // project the EntitySet 

    Assert.AreEqual(3, foos.Count()); // passes 
} 

Cela renvoie les éléments corrects avec l'instruction SQL suivante:

SELECT  [t2].[FooId], 
      [t2].[ParentFooId], 
      [t2].[Name] 
FROM  [dbo].[Foos] AS [t0] 
INNER JOIN [dbo].[Foos] AS [t1] ON [t1].[FooId] = [t0].[ParentFooId] 
CROSS JOIN [dbo].[Foos] AS [t2] 
WHERE  ([t0].[Name] = @p0) 
AND  ([t2].[ParentFooId] = [t1].[FooId]) 

Nous nous interrogeons sur la CROSS JOIN, c'est apparemment le résultat de la SelectMany?
Y a-t-il une autre façon d'aborder cela afin de ne pas avoir le CROSS JOIN?

Répondre

0

Vous pourriez aussi faire:

var query = from f in db.Foos 
      where (from fo in db.Foos 
        where fo.Name == "Two" 
        select fo.ParentId).Contains(f.ParentId) 
      select f; 

Cela devrait se traduire par quelque chose comme:

SELECT  [t1].[FooId], 
      [t1].[ParentFooId], 
      [t1].[Name] 
FROM  [dbo].[Foos] AS [t1] 
WHERE  [t1].[ParentFooId] IN (SELECT [t0].[ParentFooId] 
            FROM [dbo].[Foos] AS [t0] 
            WHERE[t0].[Name] = @p0) 

Peut différer un peu (peut-être un Exists() selon le modèle) ... Je ne sais pas avoir une fenêtre de profilage à portée de main.

1

Vous pouvez empiler à partir d'instructions dans une requête Linq et cela vous aidera probablement ici.

var query = from f in db.Foos 
      from f2 in f.Foos 
      where f.Name == "Two" 
      select f2; 

Qui produit.

SELECT [t1].[FooId], 
     [t1].[Name], 
     [t1].[ParentFooId] 
FROM [dbo].[Foos] AS [t0], [dbo].[Foos] AS [t1] 
WHERE ([t0].[Name] = @p0) AND ([t1].[ParentFooId] = [t0].[FooId]) 
+0

Donc cela va quitter le type de jointure à SQL Server depuis un n'est pas spécifié? – blu

+0

Oui. Par défaut, c'est une jointure interne. –

+0

J'ai cru comprendre que ',' laisserait la détermination de la jointure à SQL Server; il peut s'agir d'une jointure interne ou d'une jointure croisée. Si ce n'est pas une référence à cette mise en œuvre serait génial. – blu

0

Essayez ceci:

var siblings = DataContext.Foos.Where(a => a.FooID == 3) 
    .Select(b => Foos.Where(b => Foos.ParentFooID == a.ParentFooID)); 

Assert.AreEqual(3, siblings.Count()); 
+0

il vous manque une accolade de fermeture! –

+0

Merci pour la prise. –