IEnumerable<T> 上的每个方法都是一个标准查询运算符(Standard Query Operator)。 它提供了对集合进行查询的能力。
注意查询运算符和查询表达式是有区别的。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace LinqSample01 { class Program { public class Student { public string First { get; set; } public string Last { get; set; } public int ID { get; set; } public List<int> Scores; } // Create a data source by using a collection initializer. static List<Student> students = new List<Student> { new Student {First="Svetlana", Last="Omelchenko", ID=111, Scores= new List<int> {97, 92, 81, 60}}, new Student {First="Claire", Last="O’Donnell", ID=112, Scores= new List<int> {75, 84, 91, 39}}, new Student {First="Sven", Last="Mortensen", ID=113, Scores= new List<int> {88, 94, 65, 91}}, new Student {First="Cesar", Last="Garcia", ID=114, Scores= new List<int> {97, 89, 85, 82}}, new Student {First="Debra", Last="Garcia", ID=115, Scores= new List<int> {35, 72, 91, 70}}, new Student {First="Fadi", Last="Fakhouri", ID=116, Scores= new List<int> {99, 86, 90, 94}}, new Student {First="Hanying", Last="Feng", ID=117, Scores= new List<int> {93, 92, 80, 87}}, new Student {First="Hugo", Last="Garcia", ID=118, Scores= new List<int> {92, 90, 83, 78}}, new Student {First="Lance", Last="Tucker", ID=119, Scores= new List<int> {68, 79, 88, 92}}, new Student {First="Terry", Last="Adams", ID=120, Scores= new List<int> {99, 82, 81, 79}}, new Student {First="Eugene", Last="Zabokritski", ID=121, Scores= new List<int> {96, 85, 91, 60}}, new Student {First="Michael", Last="Tucker", ID=122, Scores= new List<int> {94, 92, 91, 91} } }; static void Main(string[] args) { IEnumerable<Student> studentQuery = students.Where( student => student.Scores[0] > 90 ); foreach (Student item in studentQuery) { Console.WriteLine("Name: {0} : {1}", item.Last, item.Scores[0]); } Console.ReadKey(); } } }
把查询结果转换为xml格式 (http://msdn.microsoft.com/zh-cn/library/bb397914(v=vs.90).aspx)
class XMLTransform { static void Main() { // Create the data source by using a collection initializer. List<Student> students = new List<Student>() { new Student {First="Svetlana", Last="Omelchenko", ID=111, Scores = new List<int>{97, 92, 81, 60}}, new Student {First="Claire", Last="O’Donnell", ID=112, Scores = new List<int>{75, 84, 91, 39}}, new Student {First="Sven", Last="Mortensen", ID=113, Scores = new List<int>{88, 94, 65, 91}}, }; // Create the query. var studentsToXML = new XElement("Root", from student in students let x = String.Format("{0},{1},{2},{3}", student.Scores[0], student.Scores[1], student.Scores[2], student.Scores[3]) select new XElement("student", new XElement("First", student.First), new XElement("Last", student.Last), new XElement("Scores", x) ) // end "student" ); // end "Root" // Execute the query. Console.WriteLine(studentsToXML); // Keep the console open in debug mode. Console.WriteLine("Press any key to exit."); Console.ReadKey(); } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DelayExecute { class Program { static void Main(string[] args) { // Specify the data source. int[] scores = new int[] { 97, 92, 81, 60 }; bool result = false; IEnumerable<int> scoreQuery = scores.Where( score => { result = false; if (score > 80) { result = true; Console.WriteLine("Score = {0}", score); } return result; }); Console.WriteLine("==============================================="); Console.WriteLine("1) Invoke empty foreeach, it will execute"); foreach (int i in scoreQuery) { } Console.WriteLine("==============================================="); Console.WriteLine("2) Invoke IEnumerable Count, it will execute"); scoreQuery.Count(); Console.WriteLine("==============================================="); Console.WriteLine("3) Invoke IEnumerable ToArray, it will execute"); scoreQuery = scoreQuery.ToArray(); Console.ReadKey(); } } }
这些函数和SQL中的函数使用比较类似,可以用SQL的想法帮助理解。
OrderBy() 和 ThenBy()
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace TestOrderAPI { class Program { public class Student { public string First { get; set; } public string Last { get; set; } public int ID { get; set; } public List<int> Scores; } // Create a data source by using a collection initializer. static List<Student> students = new List<Student> { new Student {First="Svetlana", Last="Omelchenko ", ID=111, Scores= new List<int> {97, 92, 81, 60}}, new Student {First="Claire ", Last="O’Donnell ", ID=112, Scores= new List<int> {75, 84, 91, 39}}, new Student {First="Sven ", Last="Mortensen ", ID=113, Scores= new List<int> {88, 94, 65, 91}}, new Student {First="Cesar ", Last="Garcia ", ID=114, Scores= new List<int> {97, 89, 85, 82}}, new Student {First="Debra ", Last="Garcia ", ID=115, Scores= new List<int> {35, 72, 91, 70}}, new Student {First="Fadi ", Last="Fakhouri ", ID=116, Scores= new List<int> {99, 86, 90, 94}}, new Student {First="Hanying ", Last="Feng ", ID=117, Scores= new List<int> {93, 92, 80, 87}}, new Student {First="Hugo ", Last="Garcia ", ID=118, Scores= new List<int> {92, 90, 83, 78}}, new Student {First="Lance ", Last="Tucker ", ID=119, Scores= new List<int> {68, 79, 88, 92}}, new Student {First="Terry ", Last="Adams ", ID=120, Scores= new List<int> {99, 82, 81, 79}}, new Student {First="Eugene ", Last="Zabokritski", ID=121, Scores= new List<int> {96, 85, 91, 60}}, new Student {First="Michael ", Last="Tucker ", ID=122, Scores= new List<int> {94, 92, 91, 91} } }; static void Main(string[] args) { IEnumerable<Student> studentQuery = students.OrderBy( student => student.Scores[0]).ThenBy(student => student.Scores[1]); foreach (Student item in studentQuery) { Console.WriteLine("Name: {0} : {1}, {2}", item.Last, item.Scores[0], item.Scores[1]); } Console.ReadKey(); } } }
用于把两个集合用某中关键字连接起来。这里用的是 TeamID
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace TestJoinAPI { class Program { public class Student { public string First { get; set; } public string Last { get; set; } public int ID { get; set; } public List<int> Scores; public int TeamID { get; set; } } public class Team { public int TeamID { get; set; } public string TeamName { get; set; } } // Create a data source by using a collection initializer. static List<Student> students = new List<Student> { new Student {First="Svetlana", Last="Omelchenko", ID=111, Scores= new List<int> {97, 92, 81, 60}, TeamID=0}, new Student {First="Claire", Last="O’Donnell", ID=112, Scores= new List<int> {75, 84, 91, 39}, TeamID=1}, new Student {First="Sven", Last="Mortensen", ID=113, Scores= new List<int> {88, 94, 65, 91}, TeamID=0}, new Student {First="Cesar", Last="Garcia", ID=114, Scores= new List<int> {97, 89, 85, 82}, TeamID=1}, new Student {First="Debra", Last="Garcia", ID=115, Scores= new List<int> {35, 72, 91, 70}, TeamID=0}, new Student {First="Fadi", Last="Fakhouri", ID=116, Scores= new List<int> {99, 86, 90, 94}, TeamID=1}, new Student {First="Hanying", Last="Feng", ID=117, Scores= new List<int> {93, 92, 80, 87}, TeamID=0}, new Student {First="Hugo", Last="Garcia", ID=118, Scores= new List<int> {92, 90, 83, 78}, TeamID=1}, new Student {First="Lance", Last="Tucker", ID=119, Scores= new List<int> {68, 79, 88, 92}, TeamID=0}, new Student {First="Terry", Last="Adams", ID=120, Scores= new List<int> {99, 82, 81, 79}, TeamID=1}, new Student {First="Eugene", Last="Zabokritski", ID=121, Scores= new List<int> {96, 85, 91, 60}, TeamID=0}, new Student {First="Michael", Last="Tucker", ID=122, Scores= new List<int> {94, 92, 91, 91}, TeamID=1 } }; // Create a data source by using a collection initializer. static List<Team> teams = new List<Team> { new Team {TeamID = 0, TeamName="Team A"}, new Team {TeamID = 1, TeamName="Team B"}, }; static void Main(string[] args) { var items = students.Join(teams, student => student.TeamID, // The key one for join team => team.TeamID, // The key two for join (student, team) => new // The new collection items { team.TeamID, team.TeamName, student.ID, student.First, }).OrderBy(team => team.TeamID); foreach (var item in items) { Console.WriteLine("Team {0} : {1} {2}", item.TeamName, item.ID, item.First); } Console.ReadKey(); } } }
用来对具有相似特征的对象进行分组。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace TestGroupByAPI { class Program { public class Student { public string First { get; set; } public string Last { get; set; } public int ID { get; set; } public List<int> Scores; public int TeamID { get; set; } } // Create a data source by using a collection initializer. static List<Student> students = new List<Student> { new Student {First="Svetlana", Last="Omelchenko", ID=111, Scores= new List<int> {97, 92, 81, 60}, TeamID=0}, new Student {First="Claire", Last="O’Donnell", ID=112, Scores= new List<int> {75, 84, 91, 39}, TeamID=1}, new Student {First="Sven", Last="Mortensen", ID=113, Scores= new List<int> {88, 94, 65, 91}, TeamID=0}, new Student {First="Cesar", Last="Garcia", ID=114, Scores= new List<int> {97, 89, 85, 82}, TeamID=1}, new Student {First="Debra", Last="Garcia", ID=115, Scores= new List<int> {35, 72, 91, 70}, TeamID=0}, new Student {First="Fadi", Last="Fakhouri", ID=116, Scores= new List<int> {99, 86, 90, 94}, TeamID=1}, new Student {First="Hanying", Last="Feng", ID=117, Scores= new List<int> {93, 92, 80, 87}, TeamID=0}, new Student {First="Hugo", Last="Garcia", ID=118, Scores= new List<int> {92, 90, 83, 78}, TeamID=1}, new Student {First="Lance", Last="Tucker", ID=119, Scores= new List<int> {68, 79, 88, 92}, TeamID=0}, new Student {First="Terry", Last="Adams", ID=120, Scores= new List<int> {99, 82, 81, 79}, TeamID=1}, new Student {First="Eugene", Last="Zabokritski", ID=121, Scores= new List<int> {96, 85, 91, 60}, TeamID=0}, new Student {First="Michael", Last="Tucker", ID=122, Scores= new List<int> {94, 92, 91, 91}, TeamID=1 } }; static void Main(string[] args) { IEnumerable<IGrouping<int, Student>> StudentGroup = students.GroupBy( (student) => student.TeamID); foreach (IGrouping<int, Student> group in StudentGroup) { Console.WriteLine("=========================================="); foreach (Student stu in group) { Console.WriteLine("Team: {0} Name: {1}", stu.TeamID, stu.First); } Console.WriteLine("=========================================="); } Console.ReadKey(); } } }
如果我们想知道一个小组中有多少个学生,这是一个一对多的映射,但 Join是一个一对一的映射,调用后还需要再次处理。
这时使用 GroupJoin() 是最合理的。他把小组ID 与 一组学生(多名学生)对应了起来。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace TestGroupJoinAPI { class Program { public class Student { public string First { get; set; } public string Last { get; set; } public int ID { get; set; } public List<int> Scores; public int TeamID { get; set; } } public class Team { public int TeamID { get; set; } public string TeamName { get; set; } } // Create a data source by using a collection initializer. static List<Student> students = new List<Student> { new Student {First="Svetlana", Last="Omelchenko", ID=111, Scores= new List<int> {97, 92, 81, 60}, TeamID=0}, new Student {First="Claire", Last="O’Donnell", ID=112, Scores= new List<int> {75, 84, 91, 39}, TeamID=1}, new Student {First="Sven", Last="Mortensen", ID=113, Scores= new List<int> {88, 94, 65, 91}, TeamID=0}, new Student {First="Cesar", Last="Garcia", ID=114, Scores= new List<int> {97, 89, 85, 82}, TeamID=1}, new Student {First="Debra", Last="Garcia", ID=115, Scores= new List<int> {35, 72, 91, 70}, TeamID=0}, new Student {First="Fadi", Last="Fakhouri", ID=116, Scores= new List<int> {99, 86, 90, 94}, TeamID=1}, new Student {First="Hanying", Last="Feng", ID=117, Scores= new List<int> {93, 92, 80, 87}, TeamID=0}, new Student {First="Hugo", Last="Garcia", ID=118, Scores= new List<int> {92, 90, 83, 78}, TeamID=1}, new Student {First="Lance", Last="Tucker", ID=119, Scores= new List<int> {68, 79, 88, 92}, TeamID=0}, new Student {First="Terry", Last="Adams", ID=120, Scores= new List<int> {99, 82, 81, 79}, TeamID=1}, new Student {First="Eugene", Last="Zabokritski", ID=121, Scores= new List<int> {96, 85, 91, 60}, TeamID=0}, new Student {First="Michael", Last="Tucker", ID=122, Scores= new List<int> {94, 92, 91, 91}, TeamID=1 } }; // Create a data source by using a collection initializer. static List<Team> teams = new List<Team> { new Team {TeamID = 0, TeamName="Team A"}, new Team {TeamID = 1, TeamName="Team B"}, }; static void Main(string[] args) { var items = teams.GroupJoin( students, team => team.TeamID, student => student.TeamID, (team, studentGroup) => new { team.TeamID, team.TeamName, students = studentGroup }); foreach (var item in items) { Console.WriteLine("Team {0} : ", item.TeamName); foreach(Student stu in item.students) { Console.WriteLine("Name: {0}, {1}", stu.First, stu.Last); } Console.WriteLine("===================================================="); } Console.ReadKey(); } } }