簡體   English   中英

通過 id 區分包含對象的列表

[英]Distinct a list with objects by id

我有一個程序,其中有一個主題(如論壇),人們可以對該主題做出反應。

用戶:

  1. 身份證
  2. 名字
  3. 姓氏

主題:

  1. 身份證
  2. 主題

反應:

  1. 身份證
  2. topic_id
  3. 內容

代碼:

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();

現在,“distinct”列表仍然有一些重復項,如何根據用戶 ID 區分列表? 或者也許有另一種更好的方法來做到這一點。 提前致謝。

您可以使用GroupBy來實現

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

Distinct有一個重載,它接收一個IEqualityComparer<T>的實例,它是一個包含允許 LINQ 知道哪兩個對象相等的邏輯的對象,因此應該消除一個。

您需要實現這個(非常簡單的)接口,如下所示:

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();
      }
}

然后將UserEqualityComparer的實例UserEqualityComparerDistinct()

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

我建議您讓數據庫為您返回不同的用戶:

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

這將被轉換為單個 SQL 查詢。 類似於(假設您的 USER 表有兩列 - Id 和 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]

MoreLinq(在 NuGet 上可用)有一個 DistincBy 方法,允許您使用委托作為相等比較器。

所以你只需要做這樣的事情:

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

編輯: MoreLinq 鏈接

我在 .Net core 中嘗試過類似的代碼。 無需定義顯式比較器。 在類中覆蓋EqualsGetHashcode 不需要GroupBy 默認情況下,即使其他道具不同, Distinct()工作。

public class User  
    {
        public int Id { get; set; }    
        public string FirstName { get; set; }            
        public string LastName { get; set; }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(this, obj)) return true;    
            if (obj is User && (obj as User).Id == this.Id) return true;    
            return false;          
        }

        public override int GetHashCode()
        {
            int hashProductCode = Id.GetHashCode();    
            return hashProductCode;
        }    
    }

User[] users =  {
                new User {Id=1, FirstName="John", LastName="Smith" },
                new User {Id=2, FirstName="Mary", LastName="Blood" },
                new User {Id=1, FirstName="Sergey", LastName="Ivanov" }
            };

            var usersDistinct = users.Distinct().ToArray();
            Console.WriteLine(usersDistinct.Count()); //2 =John + Mary

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM