通过orderby关键字,LINQ可以实现升序和降序排列。LINQ还支持次要排序(也可以按升序和降序排列),只要将需要排序的项用逗号隔开即可。
升序,将一句话中的单词拆开,然后将这些单词升序排列
string quote = "Most people have the will to win, few have the will to prepare to win."; string[] words = quote.Split(new char[] { ' ', ',', '.' }, StringSplitOptions.RemoveEmptyEntries); // 依据指定的内容进行升序排列,同时 `ascending`可以省略,因为默认执行升序排列 var sorted = from word in words orderby word ascending select word; foreach (var s in sorted) Console.WriteLine(s);降序
string quote = "Most people have the will to win, few have the will to prepare to win."; string[] words = quote.Split(new char[] { ' ', ',', '.' }, StringSplitOptions.RemoveEmptyEntries); var descending = from word in words orderby word descending select word; foreach (var s in descending) Console.WriteLine(s);扩展方法降序
string quote = "Most people have the will to win, few have the will to prepare to win."; string[] words = quote.Split(new char[] { ' ', ',', '.' }, StringSplitOptions.RemoveEmptyEntries); foreach (var s in words.OrderByDescending(s => s)) Console.WriteLine(s);次要排序
var gamblers = new[] { new {LastName="Kimmel", First="Paul", Age=41}, new {LastName="Swanson", First="Dena", Age=26}, new {LastName="Swanson", First="Joe", Age=4}, new {LastName="Kimmel", First="Noah", Age=11} }; // 在关键字 orderby 之后,列举出的项是排序依据项,其中排序优先级依次降低。同时每个依据项可天降ascending或descending关键字用于指定是升序还是降序排列 var sordid = from gambler in gamblers orderby gambler.LastName, gambler.Age select gambler; foreach (var playa in sordid) Console.WriteLine(playa); // 实现相同功能的拓展方法版本 gamblers.OrderBy(item=>item.LastName).ThenBy(item=>item.Age).Select(item=>item);反转顺序
string quote = "Most people have the will to win, few have the will to prepare to win."; string[] words = quote.Split(new char[] { ' ', ',', '.' }, StringSplitOptions.RemoveEmptyEntries); foreach (var s in words.Reverse()) Console.WriteLine(s);LINQ中的许多概念都跟SQL很相似。其中之一就是根据相似性将数据组织到逻辑分组中。在LINQ中,分组功能是通过group by子句实现的。
var nums = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; // 根据条件执行分组,该例中 n % 2 只有两个值0和1,结果被分为两组 // 如果使用 n % 3 则会被分成 3 组 var result = from n in nums group n by n % 2; // really quite funky Array.ForEach(result.ToArray(), x => { Console.WriteLine(x.Key == 0 ? "evens:" : "odds:"); Array.ForEach(x.ToArray(), y => Console.WriteLine(y)); });数据库查询 + LINQ分组
class Program { // 查询语句,内连接。左表中一条记录可连接右表中满足条件的多条记录 static string sql = "SELECT Categories.CategoryName, Products.ProductID, Products.ProductName, Products.UnitsInStock, Products.UnitPrice " + "FROM Categories INNER JOIN Products ON Categories.CategoryID = Products.CategoryID"; // 连接字符串 static string connectionString = "Server=localhost;Database=Northwind;Trusted_Connection=True;"; // 定义一个数据类,用于存储SQL查询的单条记录 public class ProductItem { public string CategoryName { get; set; } public int ProductID { get; set; } public string ProductName { get; set; } public int UnitsInStock { get; set; } public decimal UnitPrice { get; set; } public override string ToString() { const string mask = "Category Name: {0}, Product ID: {1}, Product Name: {2}, Units In Stock: {3}, Unit Price: {4}"; return string.Format(mask, CategoryName, ProductID, ProductName, UnitsInStock, UnitPrice); } } // 读取辅助类,用以判断是否为空值 static T SafeRead<T>(IDataReader reader, string name, T defaultValue) { object o = reader[name]; if (o != System.DBNull.Value && o != null) return (T)Convert.ChangeType(o, defaultValue.GetType()); return defaultValue; } static void Main(string[] args) { // 定义存储查询结果的集合 List<ProductItem> products = new List<ProductItem>(); // 执行查询 using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); SqlCommand command = new SqlCommand(sql, connection); SqlDataReader reader = command.ExecuteReader(); while (reader.Read()) { products.Add(new ProductItem { CategoryName = SafeRead(reader, "CategoryName", ""), ProductID = SafeRead(reader, "ProductID", -1), ProductName = SafeRead(reader, "ProductName", ""), UnitsInStock = SafeRead(reader, "UnitsInStock", 0), UnitPrice = SafeRead(reader, "UnitPrice", 0M) }); } } // 分割线 string line = new string('-', 40); // 定义LINQ // 将分组结果被组织到IGrouping对象中,该对象含有一个Key/Element对。 // Key代表的是含有数据的分组,而Element则代表的是数据 // 通过 into 子句将分组结果存储于指定的变量grp中 var grouped = from p in products orderby p.CategoryName, p.ProductName group p by p.CategoryName into grp select new { Category = grp.Key, Product = grp }; // 打印结果 Array.ForEach(grouped.ToArray(), g => { Console.WriteLine(g.Category); Console.WriteLine(line); // dump each product in the group Array.ForEach(g.Product.ToArray(), p => Console.WriteLine(p)); Console.WriteLine(Environment.NewLine); }); } }