C# c如何使用LINQ从对象中选择不同的项
我只想从查询中选择不同的用户名和id。目前,它正在返回重复项C# c如何使用LINQ从对象中选择不同的项,c#,linq,C#,Linq,我只想从查询中选择不同的用户名和id。目前,它正在返回重复项 TotalUsers = (from p in reports group p by new { p.UserID,
TotalUsers = (from p in reports
group p by new
{
p.UserID,
p.UserName
} into grp
select new Employee()
{
Name = grp.Key.UserName,
Id = grp.Key.UserID
}).ToList();
我尝试过使用Name=grp.Key.UserName.First.ToString,但这给出了用户名的第一个字母
当前输出示例:
{UserID=1,UserName="N1"}
{UserID=2,UserName="N2"}
{UserID=1,UserName="N1"}
{UserID=2,UserName="N2"}
期望输出:
{UserID=1,UserName="N1"}
{UserID=2,UserName="N2"}
假设您的用户密钥是ID,并且您拥有以下数据集:
Report
ID | UserID | UserName
1 | 1 | UN1
2 | 2 | UN2
3 | 3 | UN1
然后,当您需要不同的UserID、UserName对时,您将拥有两次UserName UN1,一次用于ID 1,一次用于ID 3。绕过它的唯一方法是忽略用户ID。这意味着您必须以以下方式更改为代码:
TotalUsers = (from p in reports
group p by new
{
p.UserName
} into grp
select new Employee()
{
Name = grp.Key.UserName
}).ToList();
public class UserData{
public string UserName {get;set;}
public string UserId {get;set;}
public override bool Equals(object x) {
if (! (x is UserData)) return false;
UserData y = (UserData) x;
return this.UserName == x.UserName && this.UserId == x.UserId;
}
}
TotalUsers = (from p in reports
group p by new UserData
{
UserId = p.UserId,
UserName = p.UserName
} into grp
select new Employee()
{
Name = grp.Key.UserName,
Id = grp.Key.UserId
}).ToList();
正确答案-在给出示例后编辑
如果情况并非如此,那么您的问题是您的查询从以下数据集中返回两次成对的1,UN1:
Report
ID | UserID | UserName
1 | 1 | UN1
2 | 2 | UN2
3 | 3 | UN1
4 | 1 | UN1
由于缺少Equals方法,它无法工作。您可以通过以下方式解决此问题:
TotalUsers = (from p in reports
group p by new
{
p.UserName
} into grp
select new Employee()
{
Name = grp.Key.UserName
}).ToList();
public class UserData{
public string UserName {get;set;}
public string UserId {get;set;}
public override bool Equals(object x) {
if (! (x is UserData)) return false;
UserData y = (UserData) x;
return this.UserName == x.UserName && this.UserId == x.UserId;
}
}
TotalUsers = (from p in reports
group p by new UserData
{
UserId = p.UserId,
UserName = p.UserName
} into grp
select new Employee()
{
Name = grp.Key.UserName,
Id = grp.Key.UserId
}).ToList();
我正在创建一个组,它的密钥包含${p.UserID}-{p.UserName},并且它将确保其唯一性
TotalUsers = (from p in new List<User>()
group p by $"{p.UserID}-{p.UserName}"
into grp
select new Employee()
{
Name = grp.First().UserName,
Id = grp.First().UserID
}).ToList();
如果不知道您的报表对象是什么样的,并且没有一个完整的模型,那么很难回答这个问题 我假设UserID是用户的唯一标识符。并且用户名将始终与UserID对应。如果是这样的话,下面应该给你不同的用户
TotalUsers = reports.GroupBy(x => x.UserID)
.Select(x => x.First())
.Select(x => new Employee()
{
Name = x.UserName,
Id = x.UserID
})
.ToList();
GroupBy将使用相同的用户ID整理所有项目。然后我们选择第一个项目-这完全是任意的,不知道为什么会得到重复项,这可能不是最好的解决方案-可能值得研究为什么会得到重复项,而不是解决这里的问题。然后,每一个都被转换成一个Employee对象。更新了注释。您好@HJ1990,请看我回答的第二部分,它正是您想要的。问题是动态对象没有等号的定义,因此group by不起作用:如果定义了not equals,则它们都不同于键或第一个元素,这是同一件事否?group by key,然后获取该组的第一个元素。对不起,这里的键是字符串,但对于问题中发布的代码,从key或irst元素获取用户名,这是一样的。