2012-02-15 21 views
5

Ho 2 IList<T> dello stesso tipo di oggetto ItemsDTO. Voglio escludere una lista da un'altra. Tuttavia questo non sembra funzionare per me e mi chiedevo perché?LINQ Except() Il metodo non funziona

IList<ItemsDTO> related = itemsbl.GetRelatedItems(); 
IList<ItemsDTO> relating = itemsbl.GetRelatingItems().Except(related).ToList(); 

sto cercando di rimuovere gli elementi in related dalla lista relating.

risposta

11

Poiché la classe è un tipo di riferimento, la classe ItemsDTO deve ignorare Equals e GetHashCode affinché funzioni.

+0

penso che sarebbe sufficiente per ignorare Uguale solo. Perché pensi di dover sovrascrivere GetHashCode? – gprasant

+2

@gprasant http://stackoverflow.com/questions/371328/why-is-it-important-to-override-gethashcode-when-equals-method-is-overriden-in-c – Yuck

+2

'Except' utilizza' HashSets' internamente. – Magnus

1

Da MSDN:

Produce la differenza di set di due sequenze utilizzando l'uguaglianza di confronto predefinito per confrontare i valori.

L'uguaglianza di confronto predefinita sta per essere un confronto di riferimento. Pertanto, se tali elenchi vengono compilati indipendentemente l'uno dall'altro, possono contenere gli stessi oggetti dal punto di vista dell'utente ma diversi riferimenti.

Quando si utilizza LINQ contro SQL Server si ha il vantaggio di LINQ che traduce la propria istruzione LINQ in una query SQL che può eseguire l'uguaglianza logica per l'utente in base a chiavi primarie o comparatori di valori. Con LINQ to Objects dovrai definire cosa sia l'uguaglianza logica a ItemsDTO. E questo significa sovrascrivere Equals() e GetHashCode().

+0

+1 per il caso particolare quando si utilizza Linq2Sql – Magnus

0

Tranne che funziona bene per i tipi di valore. Tuttavia, dal momento che si utilizzano tipi di Ref, è necessario eseguire l'override Equals e GethashCode sul vostro ItemsDTO al fine di arrivare a questo lavoro

0

Ho appena incontrato lo stesso problema. Apparentemente, .NET ritiene che gli elementi in una lista siano diversi dagli stessi elementi dell'altra lista (anche se in realtà sono uguali). Questo è quello che ho fatto per risolverlo:

avere la classe ereditare IEqualityComparer<T>, ad es.

public class ItemsDTO: IEqualityComparer<ItemsDTO> 
{ 
    public bool Equals(ItemsDTO x, ItemsDTO y) 
    { 
    if (x == null || y == null) return false; 

    return ReferenceEquals(x, y) || (x.Id == y.Id); // In this example, treat the items as equal if they have the same Id 
    } 

    public int GetHashCode(ItemsDTO obj) 
    { 
    return this.Id.GetHashCode(); 
    } 
} 
Problemi correlati