2012-08-09 18 views
12

tengo la siguiente expresión LINQ:distintas() no funciona

AgentsFilter = new BindableCollection<NameValueGuid>((
    from firstEntry in FirstEntries 
    select new NameValueGuid { 
     Name = firstEntry.Agent, 
     Value = firstEntry.AgentId 
    }).Distinct() 
); 

Pero debido a alguna razón, la Colección AgentsFilter está llena de duplicados. ¿Qué pasa con mi Distinct()?

Respuesta

28

Distinct utilizará el método Equals en NameValueGuid para encontrar duplicados. Si no anula Equals, comprobará las referencias.

Puede agregar un paso adicional para evitar anular Iguales, utilizando un tipo anónimo. Los tipos anónimos anulan automáticamente Equals y GetHashCode para comparar a cada miembro. Hacer lo distinto en el tipo anónimo, luego proyectar eso en su clase resolverá el problema.

from firstEntry in FirstEntries 
select new 
{ 
    Name = firstEntry.Agent, 
    Value = firstEntry.AgentId 
}).Distinct().Select(x => new NameValueGuid 
{ 
    Name = x.Name, 
    Value = x.Value 
}); 
+0

Gracias y todos los demás que respondieron. –

+1

Vote por 'Distinct usará el método Equals para encontrar duplicados. Si no anula Equals, entonces comprobará las referencias '. –

7

no podría haber suministrado una implementación de ambos GetHashCode y Equals en NameValueGuid.

Alternativamente, si eso no es posible, puede pasar una instancia de IEqualityComparer<NameValueGuid> a su llamada de Distinct.

Ver: http://msdn.microsoft.com/en-us/library/system.linq.enumerable.distinct.aspx

+0

Buena explicación, pero hay otra solución: usar tipos anónimos (ver la respuesta de * Cadrell0 *) –

+0

+1, No me di cuenta de que necesitaba anular 'GetHashCode' y' Distinct' para que funcione. Después de anularlo, parece que 'Distinct' primero llama a' GetHashCode' para determinar si necesita llamar 'Equals'. – DCShannon

4

Es necesario definir lo que significa Distinct en el contexto de una clase con Name y Value propiedades. Ver MSDN.

Pruebe la sobrecarga de Distinct que le permite proporcionar un comparador.

Por ejemplo:

AgentsFilter = new BindableCollection<NameValueGuid>((from firstEntry in FirstEntries 
    select new NameValueGuid 
    { 
     Name = firstEntry.Agent, 
     Value = firstEntry.AgentId 
    }) 
    .Distinct((nvg) => nvg.Value) 
); 

Alternativamente, si tiene acceso a la definición del código de NameValueGuid, a continuación, se puede anular GetHashCode y Equals según sea apropiado para la clase. Nuevamente, vea MSDN

4
select new 
{ 
    Name = firstEntry.Agent, 
    Value = firstEntry.AgentId 
}) 
.Distinct() 
.Select(x => new NameValueGuid 
{ 
    Name = x.Name, 
    Value = x.Value 
});