2010-11-01 5 views
4

Cela peut sembler compliqué, mais j'essaie simplement de sélectionner tous les enregistrements et leurs enfants de A où certaines conditions existent chez leurs enfants. Vous recherchez la syntaxe que je peux ajouter à la Une variable qui me permet de filtrer un tas de conditionsLinq: faire une clause Where() sur un modèle imbriqué

Si vous avez une vue imbriquée comme celui-ci (comme un modèle de spécification?):

var a = from Arow in Atable 
     where ??? 
     select new AViewModel {     // (image Products) 
      id = Arow.id, 
      name = Arow.Name, 
      Brows = (from Brow in Arow.Brows 
        select new BViewModel {  // (sold in different regions) 
         id = Brow.id, 
         name = Brow.Name, 
         Crows = (from Crow in Brow.Crows 
            select new CViewModel { // (and in many stores) 
             id = Crow.id, 
             name = Crow.Name 
            } 
        } 
     }; 

et le texte représentant requêtes à partir d'une page Web comme celui-ci (modèle spécification?) Nous avons utilisé sélecteurs JQuery pour les opérateurs (comme^= signifie « commence par »)

filter[] = { "Brow.Name = Joe", "Crow.Name = Kim" } 

Comment pourriez-vous filtrer l'expression a avec ces critères? En d'autres termes, pouvez-vous avoir une expression where comme a.Where() qui peut filtrer les propriétés imbriquées?

Ma pauvre tentative:

var b = from row in a 
     where a.Brow.Where(b => b.name == "Joe") && 
       a.Brow.Crow.Where(c => c.name == "Kim") 
     select row; 

Ce que je vraiment besoin est quelque chose comme ceci:

Select * 
from A join B on A.key = B.key join C on B.key = C.key -- propagated keys 
where exists (select null from B where A.key = B.key and B.Name = "Joe") and 
     exists (select null from C where A.key = C.key and C.Name = "Kim") 

Surtout si je peux le faire:

var result = a.Where(first).Where(second); 

Répondre

7

Votre « pauvre tentative "n'est pas si loin. Il suffit de remplacer Any() pour Where():

var b = from row in a 
     where a.Brow.Any(b => b.name == "Joe") && 
       a.Brow.Crow.Any(c => c.name == "Kim") 
     select row; 

Edité à ajouter:

Vous pouvez faire une comparaison insensible à la casse, mais, par exemple, .Any(b => b.name.Equals("Joe", StringComparison.CurrentCultureIgnoreCase)).

+0

Ceci est presque correct, ou je fais quelque chose de mal. Le fichier a.Brow.Any() fonctionne, mais l'accès au Crow en utilisant a.Brow.Crow échoue. Cependant, a.Brow.Any (p => p.Crow.Any (c => c.name == "Kim")) semble très prometteur. –

2

Ou pour le plaisir, vous pouvez faire le lambda equivilant:

var b = a.where(x => x.Brow.Any(b => b.name == "Joe") 
        && x.Brow.Crow.Any(c => c.name == "Kim") 
     .Select(y => y.row);