2011-12-16 9 views
7

Ho una lista di oggetti che alcuni di loro hanno gli stessi Id, quindi vorrei rimuovere quegli elementi che sono duplicati.Distinto nell'entità framework

Ho provato con qualcosa di simile:

List<post> posts = postsFromDatabase.Distinct().ToList(); 

Ma non funziona!

Così ho scritto questo metodo al fine di evitare i duplicati:

public List<Post> PostWithOutDuplicates(List<Post> posts) 
    { 
     List<Post> postWithOutInclude = new List<Post>(); 
     var noDupes = posts.Select(x => x.Id).Distinct(); 
     if (noDupes.Count() < posts.Count) 
     { 
      foreach (int idPost in noDupes) 
      { 
       postWithOutInclude.Add(posts.Where(x => x.Id == idPost).First()); 
      } 
      return postWithOutInclude; 
     } 
     else 
     { 
      return posts; 
     } 
    } 

Tutte le idee su come migliorare le prestazioni ??

Grazie in anticipo.

+0

Come è possibile che siano presenti ID duplicati? Sembra un problema più grande da affrontare. – Mikeb

risposta

25

Questo è bello e facile:

List<Post> posts = posts 
.GroupBy(x => x.Id) 
.Select(x => x.FirstOrDefault()) 

Ma se si desidera scrivere nel modo corretto, è vorrei consigliare di scrivere in questo modo:

public class PostComparer : IEqualityComparer<Post> 
{ 
    #region IEqualityComparer<Post> Members 

    public bool Equals(Post x, Post y) 
    { 
     return x.Id.Equals(y.Id); 
    } 

    public int GetHashCode(Post obj) 
    { 
     return obj.Id.GetHashCode(); 
    } 

    #endregion 
} 

quanto darà maggiore libertà quando si tratta di confronti aggiuntivi. avendo scritto questo corso puoi usarlo in questo modo:

List<Post> posts = postsFromDatabase.Distinct(new PostComparer()).ToList(); 
+2

Penso che in 'GetHashCode' devi usare' obj.Id.GetHashCode() 'perché l'hashcode deve essere lo stesso per due oggetti che sono uguali secondo il metodo' Equals' (almeno MSDN dice questo). – Slauma

+0

Ben avvistato! Ci dovrebbe essere Id.GetHashCode(), hai ragione. Se qualcuno è interessato: http://msdn.microsoft.com/en-us/library/ms132151.aspx –

+3

Questo lo gestirà quando i dati sono in memoria. Non bene. Utilizza il GroupBy-approch: http://stackoverflow.com/questions/8560884/how-to-implement-iequalitycomparer-to-return-distinct-values ​​ –

1

invece di .Prima(), provare .FirstOrDefault()

5

Penso che scrivere il proprio operatore di confronto personalizzato è un buon approccio.

Ecco un articolo in MSDN che spiega l'argomento molto bene: http://support.microsoft.com/kb/320727

La ragione per cui il netto non funzionano proprio che distinte() non ha idea su come detemine se ci sono uguali, quindi è con il riferimento per determinarlo è lo stesso "oggetto". Funziona come se fosse il caso di funzionare. Tutte le classi nella query non sono lo stesso oggetto.

Scrivendo il tuo comparatore (è facile) puoi dire a Distinto() come effettuare il confronto per determinare se sono uguali.

Edit: Se non si utilizza DISTINCT non è un problema e la situazione non è frecuent, la prima risposta di Piotr Justyna è semplice ed efficace.

+0

Suggerisco di utilizzare un GroupBy() se possibile. –