2012-09-06 12 views
5

Sto cercando di ottenere un conteggio dei genitori senza figli più genitori figli. Mentre scrivo mi rendo conto che è meglio spiegato con il codice di .. Quindi, qui va:Conteggio dell'associazione figlio principale schiacciato in LINQ

Con questi tipi di esempio:

public class Customer 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public List<Order> Orders { get; set; } 
} 

public class Order 
{ 
    public int Id { get; set; } 
    public string Description { get; set; } 
} 

E questi dati:

var customers = new List<Customer> 
{ 
    new Customer 
    { 
     Id = 2, 
     Name = "Jane Doe" 
    }, 
    new Customer 
    { 
     Id = 1, 
     Name = "John Doe", 
     Orders = new List<Order> 
     { 
      new Order { Id = 342, Description = "Ordered a ball" }, 
      new Order { Id = 345, Description = "Ordered a bat" } 
     } 
    } 
}; 

// I'm trying to get a count of customer orders added with customers with no orders 
// In the above data, I would expect a count of 3 as detailed below 
// 
// CId  Name  OId 
// ----  -------- ---- 
// 2  Jane Doe 
// 1  John Doe 342 
// 1  John Doe 345 

int customerAndOrdersCount = {linq call here}; // equals 3 

sto cercando per ottenere un conteggio di 3 indietro.

Grazie in anticipo per il vostro aiuto.

-Jessy Houle

aggiunto dopo:

mi ha molto colpito con tutti i grandi (e veloci) le risposte. Per gli altri che arrivano a questa domanda, cercando alcune opzioni, ecco un Test unitario con alcuni degli esempi di lavoro dal basso.

[TestMethod] 
public void TestSolutions() 
{ 
    var customers = GetCustomers(); // data from above 

    var count1 = customers.Select(customer => customer.Orders).Sum(orders => (orders != null) ? orders.Count() : 1); 
    var count2 = (from c in customers from o in (c.Orders ?? Enumerable.Empty<Order>()).DefaultIfEmpty() select c).Count(); 
    var count3 = customers.Sum(c => c.Orders == null ? 1 : c.Orders.Count()); 
    var count4 = customers.Sum(c => c.Orders==null ? 1 : Math.Max(1, c.Orders.Count())); 


    Assert.AreEqual(3, count1); 
    Assert.AreEqual(3, count2); 
    Assert.AreEqual(3, count3); 
    Assert.AreEqual(3, count4); 
} 

Ancora una volta, grazie a tutti per il vostro aiuto!

+1

+1 per fornire codice di esame utile. – sloth

risposta

5

Come su

int customerAndOrdersCount = customers.Sum(c => c.Orders==null ? 1 : Math.Max(1, c.Orders.Count())); 
+1

Forse ho perso una parte della domanda, ma perché il 'Math.Max'? –

+0

Penso di poter rispondere personalmente alla mia domanda: perché 'Orders.Count()' possibile potrebbe essere 0 ma dovrebbe essere conteggiato come 1 (perché tutti i clienti devono essere contati). +1 –

+0

Nell'industria, la velocità di commercializzazione è MOLTO importante. Grazie per la pronta risposta. –

0

È probabbly alla ricerca di qualcosa di simile:

customers.GroupBy(customer=>customer). //group by object iyself 
     Select(c=>      //select 
        new 
        { 
         ID = c.Key.Id,        
         Name = c.Key.Name, 
         Count = (c.Key.Orders!=null)? c.Key.Orders.Count():0 
        } 
       ); 
1

Se volete inizializzare che la proprietà dell'Ordine con un elenco vuoto invece di un nulla, si potrebbe fare:

int count = 
    (
    from c in customers 
    from o in c.Orders.DefaultIfEmpty() 
    select c 
).Count(); 

Se si decide di mantenere la proprietà non inizializzata in giro, poi invece fare:

int count = 
    (
    from c in customers 
    from o in (c.Orders ?? Enumerable.Empty<Order>()).DefaultIfEmpty() 
    select c 
).Count(); 
1
customers 
    .Select(customer => customer.Order) 
    .Sum(orders => (orders != null) ? orders.Count() : 1) 
0
var orderFreeCustomers = customers.Where(c=>c.Orders== null || c.Orders.Any()==false); 

var totalOrders = customers.Where (c => c.Orders !=null). 
Aggregate (0,(v,e)=>(v+e.Orders.Count) ); 

risultato è la somma di questi due valori

1

Questo funziona se si desidera contare "no ordini" come 1 e contare gli ordini altrimenti:

int customerOrders = customers.Sum(c => c.Orders == null ? 1 : c.Orders.Count()); 

By the wa y, la domanda è molto esemplare.

Problemi correlati