我有一个程序,其中有一个主题(如论坛),人们可以对该主题做出反应。
USER:
TOPIC:
反应:
代码:
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区分列表?或者也许有另一种更好的方法来做到这一点。提前谢谢。
答案 0 :(得分:17)
您可以使用GroupBy来实现
var ListOfUsers = ListOfAllUsers.GroupBy(x => x.Id)
.Select(g => g.First())
.ToList();
答案 1 :(得分:3)
我建议您让数据库为您返回不同的用户:
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]
答案 2 :(得分:2)
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
的实例传递给Distinct()
:
var ListOfUsers = ListOfAllUsers.Distinct(new UserEqualityComparer()).ToList();
答案 3 :(得分:1)
MoreLinq(在NuGet上可用)有一个DistincBy方法,允许您将委托用作相等比较器。
所以你只需做这样的事情:
var ListOfUsers = ListOfAllUsers.DistinctBy(user => user.id).ToList();
答案 4 :(得分:0)
我在 .Net core 中尝试过类似的代码。无需定义显式比较器。
在类中覆盖 Equals
和 GetHashcode
。
无需GroupBy
。默认情况下,即使其他 props 不同,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