实际开发中肯定不是排序数字列表这么简单,再给你举一个不那么“多此一举”的例子(继续拿上一篇中的 User 类):
1 2 3 4 5 6 7 8 9 10
enum Status { Offline, Online } classUser { publicint Id { get; set; } public Status Status { get; set; } }
如果有个 User 列表,就能这么写:
1
users.OrderBy(user=>user.Id)
这里的含义是,把 users 列表,按照其每个 User 类实例(命名为 user)的 Id 排序。
我们把其等价声明式查询拿出来——
1
from user in users orderby user.Id select user
比对一下吧!把每个部分这么一对应,是不是声明式查询和方法查询都变得十分清晰了呢?
分组 Group
还记得上一篇文章里面介绍的分组吗?现在也来介绍一下吧!
我们先拿出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
User[] users = new User[] { new User { Id = 1, Status = Status.Online }, new User { Id = 2, Status = Status.Online }, new User { Id = 3, Status = Status.Offline }, new User { Id = 4, Status = Status.Online }, }; var result=from user in users orderby user.Id group user by user.Status into userGroup select userGroup; foreach (vargroupin result) { Console.WriteLine("Group " + group.Key); foreach (var item ingroup) { Console.WriteLine("User ID #" + item.Id + " Status: " + item.Status); } }
User[] users = new User[] // 不变 { new User { Id = 1, Status = Status.Online }, new User { Id = 2, Status = Status.Online }, new User { Id = 3, Status = Status.Offline }, new User { Id = 4, Status = Status.Online }, }; Message[] messages = new Message[] // 来构造一个示例消息列表 { new Message {SenderId= 1,Text="I love this."}, new Message {SenderId= 2,Text="No wayyyyy we can leave message" }, new Message{SenderId=3,Text="OMG this is crazy"}, new Message{SenderId=3,Text="Great work!"}, new Message{SenderId=4,Text="Can I delete my message???"} }; var result = from message in messages join user in users on message.SenderId equals user.Id selectnew { SenderId = message.SenderId, Text = message.Text, UserStatus = user.Status, }; foreach (var item in result) { Console.WriteLine("Message [" + item.Text + "] from user #" + item.SenderId + " whose status is " + item.UserStatus); }
现在我们来看这个 Join——来试试输入吧!
1
messages.Join( // 试着打这些
IDE 里面智能提示太长了放不下!我们去 Microsoft Learn 查一下这个方法(阅读文档是一种非常好的学习方式)。
Correlates the elements of two sequences based on matching keys.
由于这是一个扩展方法(此处不展开),所以带着 this 的参数直接忽略,它表示 .Join 前面的那个对象。
Inner: The sequence to join to the first sequence.
也就是说,第一个参数是需要拼接到目标对象的序列。我们的情境下,是 users 序列。
下面的两个参数是:
A function to extract the join key from each element of the first sequence.
A function to extract the join key from each element of the second sequence.
A function to create a result element from two matching elements.
注意了!由于我们有两个序列,所以需要 2 个参数的匿名方法。两个参数就不可以省略括号了。
1 2 3 4 5 6
(message, user) => new { SenderId = user.Id, Text = message.Text, UserStatus = user.Status, }
完美!现在让我们展示一下最终的结果。
1 2 3 4 5 6 7
var result = messages.Join(users, message => message.SenderId, user => user.Id, (message, user) => new { SenderId = user.Id, Text = message.Text, UserStatus = user.Status, });