2009-08-21 7 views
0

Beispiel: Ich habe eine speicherinterne Kundenliste. Jeder Kunde hat eine Liste von Bestellungen. Jede Bestellung hat eine Liste von Artikeln. Jeder Artikel hat einen Artikelcode.Auswählen, Gruppieren in untergeordneter Liste -> Einzelne Anweisung angefordert

Ich brauche eine Liste von Artikeln, gruppiert nach dem Artikelcode, darunter die Kunden, die diesen Artikel bestellt haben. Wenn ein Kunde einen Artikel zweimal oder öfter bestellt, sollte er trotzdem als Einzelperson angezeigt werden.

Es ist eine Abfrage, die ich tun kann, aber nicht in einem einzigen LINQ-Befehl. Kann es in einer einzigen Aussage gemacht werden? Es ist mir egal, dass es 20 Zeilen sind, solange es eine einzige Abfrage ist.

Dies ist eine Herausforderung! Schlage keine anderen Lösungen vor. ;-)

Antwort

2

Diese Sie eine Liste von Objekten erhält, die jeweils ein Element und eine eindeutige Liste von Kunden, die sie gekauft:

var items = 
    customers 
    .SelectMany(c => c.Orders.SelectMany(
     o => o.Items.Select(i => new { item = i, customer = c }) 
    )) 
    .GroupBy(o => o.item.ItemCode) 
    .Select(g => new { 
     item = g.First().item, 
     customers = g.Select(o => o.customer).Distinct() 
    }); 

Testdaten:

Customer[] customers = { 
    new Customer("John Doe", new Order("A", "B")), 
    new Customer("Jane Doe", new Order("B", "C", "D"), new Order("B", "D")), 
    new Customer("Ford Prefect", new Order("D"), new Order("A", "E")) 
}; 

Ergebnis:

A: John Doe, Ford Prefect 
B: John Doe, Jane Doe 
C: Jane Doe 
D: Jane Doe, Ford Prefect 
E: Ford Prefect 
1
var query = customers 
    .SelectMany 
    (
     c => c.Orders 
      .SelectMany(o => o.Items) 
      .Select(i => new { Customer = c, i.ItemCode }) 
      .Distinct() 
    ) 
    .GroupBy(x => x.ItemCode, x => x.Customer); 

// and to quickly display the results... 
foreach (var result in query) 
{ 
    Console.WriteLine("Item code: " + result.Key); 

    Console.Write("Bought by: "); 
    foreach (var customer in result) 
    { 
     Console.Write(customer.Name + ", "); 
    } 

    Console.WriteLine(); 
    Console.WriteLine("----------"); 
} 
Verwandte Themen