使用linq从列表<t> </t>返回一组数据

时间:2014-10-15 16:47:09

标签: c# linq ienumerable

我有以下代码:

public class UserList
    {
        public string UName { get; set; }
        public string Auth { get; set; }
        public Boolean PUser { get; set; }
    }


    class DeveloperPreview
    {
        List<UserList> UserList = new List<UserList>();
        public void PopulateUsers()
        {
            UserList.Add(new UserList() { UName="Daryl",Auth="12345",PUser=true});
            UserList.Add(new UserList() { UName = "Test", Auth = "239", PUser = false });
            UserList.Add(new UserList() { UName="Developer",Auth="2",PUser=true});

        }

        public string Authenticateuser(string Username, string Auth)
        {
            var User = UserList.Where((t => t.UName.Contains(Username)));
            return User.UName;
        }

    }

由以下人员调用:

    DeveloperPreview Dev = new DeveloperPreview();
    private void SubmitClick(object sender, RoutedEventArgs e)
    {
        Dev.PopulateUsers();
        string Auth = Dev.Authenticateuser("Daryl","2");
        MessageBox.Show(Auth);
    }

我无法仅返回列表中包含&​​#34; Daryl&#34;的行。

我已将此作为参考使用:C# LINQ select from list

但是我仍然有一些 - 如何实际执行此任务有什么困难,我后来希望操纵/使用从列表中收集的数据,但这是将在必要时构建的另一个桥梁

5 个答案:

答案 0 :(得分:4)

问题在于以下几行:

 var User = UserList.Where((t => t.UName.Contains(Username)));
 return User.UName;

Enumerable.Where将返回IEnumerable<T>,这是一组记录而非单个记录。因此,稍后当您尝试访问User.UName时,您将收到错误消息。您需要选择一条记录。您可以根据自己的要求使用First / FirstOrDefault / Single / SingleOrDefault。你的方法可能是:

public string Authenticateuser(string Username, string Auth)
{
    var User = UserList.FirstOrDefault(t => t.UName.Contains(Username));
    if(User != null)    
       return User.UName;
    else  //user not found
       return null;//throw exception / Message etc
}

阅读:LINQ Single vs SingleOrDefault vs First vs FirstOrDefault

答案 1 :(得分:1)

我认为你真正需要做的就是改变这个:

var User = UserList.Where((t => t.UName.Contains(Username)));

到此:

var User = UserList.Where((t => t.UName.Contains(Username))).FirstOrDefault();

Where语句返回一个IEnumerable,你需要IEnumerable的第一个结果。

答案 2 :(得分:1)

此:

var User = UserList.Where((t => t.UName.Contains(Username)));

返回IEnumerable<T>,而不是单个项目。你可能想要的是:

var User = UserList.Where((t => t.UName.Contains(Username))).FirstOrDefault();

这将返回第一个匹配的项目(如果没有找到,则返回null)。

答案 3 :(得分:1)

您可以使用:

var User = UserList.Where(t => t.UName == Username).FirstOrDefault();

我不知道它是否会引起问题,但是拥有与对象名称匹配的属性名称可能会让人感到困惑。您正在使用&#34; UserList&#34;表示UserList对象列表。

我认为这会更有意义:

public class User
{
    public string UName { get; set; }
    public string Auth { get; set; }
    public Boolean PUser { get; set; }
}

class DeveloperPreview
{
    List<User> UserList = new List<User>();
    public void PopulateUsers()
    {
        UserList.Add(new User() { UName="Daryl",Auth="12345",PUser=true});
        UserList.Add(new User() { UName = "Test", Auth = "239", PUser = false });
        UserList.Add(new User() { UName="Developer",Auth="2",PUser=true});

    }

    public string Authenticateuser(string Username, string Auth)
    {
        var user = UserList.Where(t => t.UName == Username).FirstOrDefault();
        return user.UName;
    }

}

答案 4 :(得分:1)

这里发生的事情是.Where正在缩小列表范围,但总会返回IEnumerable&lt;&gt;,即使该枚举只包含一个元素。如果要返回单行,则需要添加对以下方法之一的调用

  • .First()返回第一个元素,如果没有第一个元素则返回错误
  • .FirstOrDefault()返回第一个元素,如果没有
  • 则返回null
  • .Single()返回单个对象,如果没有一个对象,则返回错误
  • .SingleOrDefault()返回单个对象,如果没有则返回null,如果有多个则返回错误

请注意,除了这些扩展方法之外的所有方法都会返回IEnumerable,以便您可以对它们进行链接调用,例如

UserList
    .Where( t => t.UName.Contains(Username) )
    .Select( t => t.UName )
    .DefaultIfEmpty(string.Empty)
    .First();