2008-09-09 10 views
48

Je suis un peu coincé là-dessus. Fondamentalement, je veux faire quelque chose comme la requête SQL suivante dans LINQ to SQL:Comment gérer une sous-requête IN avec LINQ to SQL?

SELECT f.* 
FROM Foo f 
WHERE f.FooId IN (
    SELECT fb.FooId 
    FROM FooBar fb 
    WHERE fb.BarId = 1000 
) 

Toute aide serait accueillie avec reconnaissance.

Merci.

Répondre

55

Jetez un oeil à this article. Fondamentalement, si vous voulez obtenir l'équivalent de IN, vous devez d'abord construire une requête interne, puis utiliser la méthode Contient(). Voici ma tentative de traduction:

var innerQuery = from fb in FoorBar where fb.BarId = 1000 select fb.FooId; 
var result = from f in Foo where innerQuery.Contains(f.FooId) select f;
+0

Merci pour le lien - c'était exactement ce dont j'avais besoin. Merci à tous les autres pour leurs réponses. –

+2

Vous pourriez avoir de meilleures performances avec la construction d'un dictionnaire avec la première requête, car l'appel Contains() dans la deuxième requête peut alors être fait dans O (1) par opposition à O (n). –

+7

Daren, LINQ to SQL sera transformé en requête SQL. Le dictionnaire sera utile lors de l'itération sur la collection d'objets. – aku

2

Essayez d'utiliser deux étapes distinctes:

// create a Dictionary/Set/Collection fids first 
var fids = (from fb in FooBar 
      where fb.BarID = 1000 
      select new { fooID = fb.FooID, barID = fb.BarID }) 
      .ToDictionary(x => x.fooID, x => x.barID); 

from f in Foo 
where fids.HasKey(f.FooId) 
select f 
3
from f in Foo 
    where f.FooID == 
     (
      FROM fb in FooBar 
      WHERE fb.BarID == 1000 
      select fb.FooID 

     ) 
    select f; 
+8

Est-ce vraiment? J'ai des difficultés à croire ... –

0

Essayez cette

var fooids = from fb in foobar where fb.BarId=1000 select fb.fooID 
var ff = from f in foo where f.FooID = fooids select f 
80

manière générale à mettre en œuvre dans LINQ to SQL

var q = from t1 in table1 
     let t2s = from t2 in table2 
        where <Conditions for table2> 
        select t2.KeyField 
     where t2s.Contains(t1.KeyField) 
     select t1; 

manière générale de mettre en œuvre EXISTE dans LINQ to SQL

var q = from t1 in table1 
     let t2s = from t2 in table2 
        where <Conditions for table2> 
        select t2.KeyField 
     where t2s.Any(t1.KeyField) 
     select t1; 
+0

Rapide et précis - bonne réponse. Même si la construction de la requête interne dans une déclaration distincte est définitivement claire, pourrait aussi bien savoir comment le faire en ligne. Merci! –

+0

@aku Cette méthode est-elle préférable à la méthode de @Samuel Jack? –

+0

Ceci est beaucoup plus lisible que la syntaxe de chaînage de méthodes. Merci. –

0
var foos = Foo.Where<br> 
(f => FooBar.Where(fb.BarId == 1000).Select(fb => fb.FooId).Contains(f.FooId)); 
1

// créer un dictionnaire/ensemble/collection en premier

Find Other Artilces

var fids = (from fb in FooBar 
      where fb.BarID = 1000 
      select new { fooID = fb.FooID, barID = fb.BarID }) 
      .ToDictionary(x => x.fooID, x => x.barID); 

from f in Foo 
where fids.HasKey(f.FooId) 
select f 
0

// créer un dictionnaire/Set/Collection fids premier

Find Other Artilces

var fids = (from fb in FooBar where fb.BarID = 1000 select new { fooID = fb.FooID, barID = fb.BarID }) .ToDictionary(x => x.fooID, x => x.barID); 

from f in Foo where fids.HasKey(f.FooId) select f 
0
from f in foo 
where f.FooID equals model.FooBar.SingleOrDefault(fBar => fBar.barID = 1000).FooID 
select new 
{ 
f.Columns 
};