Tener las siguientes clases (muy simplificada):

public class Child
{
    public string Label;
    public int CategoryNumber;
    public int StorageId;
}

public class Parent
{
    public string Label;
    public List<Child> Children = new List<Child>();
}

Y tener los siguientes datos:

var parents = new List<Parent>();

var parent = new Parent() {Label="P1"};
parent.Children.Add(new Child() {Label="C1", CategoryNumber=1, StorageId=10});
parent.Children.Add(new Child() {Label="C2", CategoryNumber=2, StorageId=20});
parents.Add(parent);

parent = new Parent() {Label="P2"};
parent.Children.Add(new Child() {Label="C3", CategoryNumber=1, StorageId=10});
parent.Children.Add(new Child() {Label="C4", CategoryNumber=2, StorageId=30});
parents.Add(parent);

parent = new Parent() {Label="P3"};
parent.Children.Add(new Child() {Label="C5", CategoryNumber=3, StorageId=10});
parent.Children.Add(new Child() {Label="C6", CategoryNumber=2, StorageId=40});
parents.Add(parent);

Ahora, ¿cómo puedo obtener una lista de los niños (con Númerodecategoría=2) de la lista de los padres que contienen al menos un niño con Númerodecategoría = 1 ?

Puedo hacer lo siguiente pero no parece ser la mejor:

var validParents = from p in parents
                   where p.Children.Any (c => c.CategoryNumber==1)
                   select p;
var selectedChildren = validParents.Select(p => from c in p.Children 
                                                where c.CategoryNumber == 2
                                                select c);

Aquí es lo que me pasa por selectedChildren:

  • IEnumerable<IEnumerable<Child>>
    • IEnumerable<Child>
      • C2 2 20
    • IEnumerable<Child>
      • C4 2 30

Es posible tener un solo plano de la lista que contiene los dos niños los elementos, en vez de dos sub-lista? ¿Cómo podría traducir en LINQ ?

InformationsquelleAutor Stécy | 2009-06-22

2 Comentarios

  1. 43

    Scott‘s respuesta es genial; me gustaría señalar que, de hecho, puede hacer esta consulta con consulta continuación sintaxis:

    from parent in parents 
    where parent.Children.Any (c => c.CategoryNumber==1)
    select parent into p
    from child in p.Children
    where child.CategoryNumber == 2
    select child

    Observe cómo la «a» le permite canalizar el resultado de una consulta en la siguiente consulta. Bastante ingenioso, eh?

    • Sí, la consulta de LINQ sintaxis es muy agradable (y probablemente un poco mejor para usar en contraposición a la mezcla de la consulta y de la extensión de la sintaxis de método). Siempre que me encuentro con este tema, yo sin embargo siento que LINQ es la falta de un operador de concatenación (similar a la Ss.concat en F#), que podría ser utilizado como una alternativa a la SelectMany, y es de hecho muy útil en otros casos. Una simple sobrecarga de la Enumerable.Concat método que toma un IEnumerable<IEnuerable<T>> parámetro iba a hacer el trabajo muy bien. Cualquier pensamiento (o incluso mejor, planes) con respecto a este?
    • Ah, parece MoreLINQ que hace es definir este operador: code.google.com/p/morelinq/wiki/OperatorsOverview. Sería muy bueno tener en la BCL aunque (junto con algunos otros, tales como Zip).
    • gracias… me salvaste el día
  2. 49

    Puede encadenar un par de consultas juntos, usando SelectMany y Donde.

    var selectedChildren = (from p in parents
                           where p.Children.Any (c => c.CategoryNumber==1)
                           select p)
                           .SelectMany(p => p.Children)
                           .Where(c => c.CategoryNumber == 2);
    
    //or...
    
    var selectedChildren = parents
                             .Where(p => p.Children.Any(c => c.CategoryNumber == 1))
                             .SelectMany(p => p.Children)
                             .Where(c => c.CategoryNumber == 2);
    • Funciona muy bien! SelectMany parece ser un método útil. ¿Tiene alguna sugerencia para un sitio web o un libro acerca de la plena comprensión de Linq?
    • Para los sitios, el que usted está en que es bueno – la mayoría de mis linq problemas se han resuelto con una búsqueda rápida o publicado pregunta aquí. el único libro que me he mirado es este… amazon.com/…
    • Gracias por proporcionar más de una sintaxis!

Dejar respuesta

Please enter your comment!
Please enter your name here