2013-12-18 6 views
5

Ich habe ein Programm, wo es ein Thema (wie ein Forum) gibt, können die Menschen auf dieses Thema reagieren.Distinct eine Liste mit Objekten von ID

USER:

  1. id
  2. Vorname
  3. Nachname

THEMA:

  1. id
  2. Thema

REAKTION:

  1. id
  2. topic_id
  3. Inhalt

Code:

List<USER> ListOfAllUsers = new List<USER>(); 
var AllReactions = from r in db.REACTIONs 
        where r.topic_id == _topic_id 
        select r; 

foreach (var itemX in AllReactions) 
{ 
    ListOfAllUsers.Add(itemX.USER); 
} 

//Distinct the list of duplicates 
var ListOfUsers = ListOfAllUsers.Distinct().ToList(); 

Nun wird die "distinct" -Liste hat noch einige Dubletten, wie Unterscheide ich die Liste? basierend auf der Benutzer-ID? Oder vielleicht gibt es einen anderen besseren Weg, dies zu tun. Danke im Voraus.

Antwort

10

Sie können GroupBy verwenden, um zu erreichen, dass

var ListOfUsers = ListOfAllUsers.GroupBy(x => x.Id) 
            .Select(g => g.First()) 
            .ToList(); 
+1

Dank, es funktioniert für mich! –

+0

und downvote ist für?OP sagte, es funktionierte für ihn – wudzik

+1

+1 Zustimmen, Lösung funktioniert. Es sollte nicht downvoted werden (besonders ohne irgendwelche Kommentare) –

3

Ich schlage vor, Sie Datenbank verschiedene Benutzer für Sie zu lassen:

List<USER> ListOfAllUsers = 
     db.REACTIONs.Where(r => r.topic_id == _topic_id) 
        .Select(r => r.USER) 
        .Distinct() 
        .ToList(); 

, die in einzelne SQL-Abfrage übersetzt werden. So etwas wie (übernehmen Ihre USER-Tabelle hat zwei Spalten - Id und Name):

SELECT 
    [Distinct1].[Id] AS [Id], 
    [Distinct1].[Name] AS [Name] 
    FROM (SELECT DISTINCT 
     [Extent2].[Id] AS [Id], 
     [Extent2].[Name] AS [Name] 
     FROM [dbo].[USER] AS [Extent1] 
     INNER JOIN [dbo].[REACTION] AS [Extent2] 
      ON [Extent1].[Id] = [Extent2].[UserId] 
     WHERE @id = [Extent1].[topic_id] 
    ) AS [Distinct1] 
2

Distinct hat eine Überlastung, die eine Instanz von IEqualityComparer<T> empfängt, die ein Objekt, das die Logik enthält, die LINQ, welche zwei Objekte zu wissen erlaubt sind gleich, und daher sollte man eliminiert werden.

Sie benötigen diese (sehr einfach) Schnittstelle zu implementieren, etwa so:

public class UserEqualityComparer : IEqualityComparer<User> 
{ 
     public bool Equals(User x, User y) 
     { 
      return x.Id == y.Id; 
     } 

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

Und dann eine Instanz von UserEqualityComparer-Distinct() passieren:

var ListOfUsers = ListOfAllUsers.Distinct(new UserEqualityComparer()).ToList(); 
+0

Gibt es irgendwelche Vorteile/Nachteile im Vergleich zur Linq-Lösung? –

1

MoreLinq (auf NuGet) hat eine DistincBy-Methode, mit der Sie einen Delegaten als Gleichheitsvergleich verwenden können.

So haben Sie nur so etwas zu tun:

var ListOfUsers = ListOfAllUsers.DistinctBy(user => user.id).ToList(); 

Edit: MoreLinq Link

+0

Hier finden Sie distinctby Erweiterung Methode Code: http://StackOverflow.com/a/20397508/1714342 – wudzik