Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# c如何使用LINQ从对象中选择不同的项_C#_Linq - Fatal编程技术网

C# c如何使用LINQ从对象中选择不同的项

C# c如何使用LINQ从对象中选择不同的项,c#,linq,C#,Linq,我只想从查询中选择不同的用户名和id。目前,它正在返回重复项 TotalUsers = (from p in reports group p by new { p.UserID,

我只想从查询中选择不同的用户名和id。目前,它正在返回重复项

                  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元素获取用户名,这是一样的。