2010-11-22 10 views
20
Customer customerOne = new Customer("John", "Doe"); 
Customer customerTwo = new Customer("Super", "Man"); 
Customer customerThree = new Customer("Crazy", "Guy"); 
Customer customerFour = new Customer("Jane", "Doe"); 
Customer customerFive = new Customer("Bat", "Man"); 

List<Customer> customers = new List<Customer>(); 
customers.Add(customerOne); 
customers.Add(customerTwo); 
customers.Add(customerThree); 
customers.Add(customerFour); 
customers.Add(customerFive); 

¿Qué consulta LINQ devolvería un enumerable para todos los clientes con el mismo apellido?¿Cómo se usa LINQ para encontrar el duplicado de una propiedad específica?

Los resultados deben incluir una instancia de: John Doe, Jane Doe, Super Man, y el hombre del palo

Respuesta

11
var result = from c in customers 
       join c2 in customers on c.LastName equals c2.LastName 
       where c != c2 
       select c; 
+2

esto es sintácticamente un poco más elegante que la solución "agrupar por", pero también (mucho) menos rendimiento (aunque obviamente la diferencia solo se nota con listas muy grandes) – jeroenh

+0

De acuerdo. ¿Es O (n sqrt (n)) vs O (n^2)? –

+0

Sería interesante ver si esto es realmente más eficaz cuando se consulta con SQL; una auto unión es probablemente más natural para un optimizador de consultas, aunque no estoy seguro de qué tipo de SQL produciría el proveedor para la solución Group By. –

7
var groups = customers.GroupBy(c => c.LastName).Where(g => g.Skip(1).Any()); 
foreach(var group in groups) { 
    Console.WriteLine(group.Key); 
    foreach(var customer in group) { 
     Console.WriteLine("\t" + customer.FirstName); 
    } 
} 

Salida:

Doe 
     John 
     Jane 
Man 
     Super 
     Bat 

Usted puede aplanar la secuencia resultante de los grupos en una secuencia con

var list = groups.SelectMany(g => g); 
23
customers.GroupBy(c => c.LastName).Where(g => g.Skip(1).Any()).SelectMany(c => c) 

o con la sintaxis de LINQ:

 var q = from c in customers 
       group c by c.LastName into g 
       where g.Skip(1).Any() 
       from c in g 
       select c; 
+0

tardó mucho tiempo para encontrar a este. ¡Gracias! – Wrightboy

Cuestiones relacionadas