您的问题似乎不完整,您是想询问关于C语言编程的某个具体问题吗?比如C语言的语法、编程技巧、项目开发等。请提供更具体的信息,这样我才能给出更准确的回答。

2026-03-31 10:141阅读0评论SEO基础
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计3768个文字,预计阅读时间需要16分钟。

您的问题似乎不完整,您是想询问关于C语言编程的某个具体问题吗?比如C语言的语法、编程技巧、项目开发等。请提供更具体的信息,这样我才能给出更准确的回答。

目录+相关阅读+示例业务背景介绍+一、筛选操作符+结果:1、引⽤器筛选+2、类型筛选OfType+二、投影操作符+1、Select+子句+结果:对应的lambda表达式+2、复合的From子句+三、let子句+四、

目录
  • 相关阅读
  • 示例业务背景介绍
  • 一、筛选操作符
    • 结果:
    • 1、索引器筛选
    • 2、类型筛选OfType
  • 二、投影操作符
    • 1、Select 子句
      • 结果:
      • 相应的lambda表达式:
    • 2、复合的From子句
    • 三、let子句
      • 四、排序操作符
        • 使用ThenBy() 和 ThenByDescending() 方法继续排序进行二次排序
        • 五、分组操作符
          • 1、对嵌套的对象分组
            • 2、多字段分组
              • 3、分组后再每组里面仅取满足条件的行

              相关阅读

              C#使用LINQ查询操作符实例代码(一)

              C#使用LINQ查询操作符实例代码(二)

              示例业务背景介绍

              示例参考《C#高级编程(第六版)》LINQ章节(P267 - P296),进行改编。

              打开示例代码我们看到:

              1、Racer.cs车手冠军信息类

              定义一级方程式世界车手冠军信息。

              2、Team.cs车队冠军信息类

              定义一级方程式世界车队冠军信息。

              3、Formula1.cs 一级方程式类

              包含两个重要静态方法:(F1是"Formula One"的缩写)

              • GetChampions():返回一组车手列表。这个列表包含了1950到2007年之间的所有一级方程式世界车手冠军
              • GetContructorChampions():返回一组车队列表。这个列表包含了1985到2007年之间的所有一级方程式世界车队冠军。

              [Serializable] public class Racer : IComparable<Racer>, IFormattable, IEquatable<Racer> { public string FirstName { get; set; } public string LastName { get; set; } public int Wins { get; set; } public string Country { get; set; } public int Starts { get; set; } public string[] Cars { get; set; } public int[] Years { get; set; } public string ToString(string format, IFormatProvider formatProvider) { switch (format) { case null: case "N": return ToString(); case "F": return FirstName; case "L": return LastName; case "C": return Country; case "S": return Starts.ToString(); case "W": return Wins.ToString(); case "A": return String.Format("{0} {1}, {2}; starts: {3}, wins: {4}", FirstName, LastName, Country, Starts, Wins); default: throw new FormatException(String.Format( "Format {0} not supported", format)); } } public bool Equals(Racer other) { return this.FirstName == other.FirstName && this.LastName == other.LastName; } public int CompareTo(Racer other) { return this.LastName.CompareTo(other.LastName); } public string ToString(string format) { return ToString(format, null); } public override string ToString() { return String.Format("{0} {1}", FirstName, LastName); } } public class Team { public string Name { get; set; } public int[] Years { get; set; } } public class Formula1 { //返回车手冠军列表 public static List<Racer> GetChampions() { List<Racer> racers = new List<Racer>(40); racers.Add(new Racer() { FirstName = "Nino", LastName = "Farina", Country = "Italy", Starts = 33, Wins = 5, Years = new int[] { 1950 }, Cars = new string[] { "Alfa Romeo" } }); racers.Add(new Racer() { FirstName = "Alberto", LastName = "Ascari", Country = "Italy", Starts = 32, Wins = 10, Years = new int[] { 1952, 1953 }, Cars = new string[] { "Ferrari" } }); racers.Add(new Racer() { FirstName = "Juan Manuel", LastName = "Fangio", Country = "Argentina", Starts = 51, Wins = 24, Years = new int[] { 1951, 1954, 1955, 1956, 1957 }, Cars = new string[] { "Alfa Romeo", "Maserati", "Mercedes", "Ferrari" } }); racers.Add(new Racer() { FirstName = "Mike", LastName = "Hawthorn", Country = "UK", Starts = 45, Wins = 3, Years = new int[] { 1958 }, Cars = new string[] { "Ferrari" } }); racers.Add(new Racer() { FirstName = "Phil", LastName = "Hill", Country = "USA", Starts = 48, Wins = 3, Years = new int[] { 1961 }, Cars = new string[] { "Ferrari" } }); racers.Add(new Racer() { FirstName = "John", LastName = "Surtees", Country = "UK", Starts = 111, Wins = 6, Years = new int[] { 1964 }, Cars = new string[] { "Ferrari" } }); racers.Add(new Racer() { FirstName = "Jim", LastName = "Clark", Country = "UK", Starts = 72, Wins = 25, Years = new int[] { 1963, 1965 }, Cars = new string[] { "Lotus" } }); racers.Add(new Racer() { FirstName = "Jack", LastName = "Brabham", Country = "Australia", Starts = 125, Wins = 14, Years = new int[] { 1959, 1960, 1966 }, Cars = new string[] { "Cooper", "Brabham" } }); racers.Add(new Racer() { FirstName = "Denny", LastName = "Hulme", Country = "New Zealand", Starts = 112, Wins = 8, Years = new int[] { 1967 }, Cars = new string[] { "Brabham" } }); racers.Add(new Racer() { FirstName = "Graham", LastName = "Hill", Country = "UK", Starts = 176, Wins = 14, Years = new int[] { 1962, 1968 }, Cars = new string[] { "BRM", "Lotus" } }); racers.Add(new Racer() { FirstName = "Jochen", LastName = "Rindt", Country = "Austria", Starts = 60, Wins = 6, Years = new int[] { 1970 }, Cars = new string[] { "Lotus" } }); racers.Add(new Racer() { FirstName = "Jackie", LastName = "Stewart", Country = "UK", Starts = 99, Wins = 27, Years = new int[] { 1969, 1971, 1973 }, Cars = new string[] { "Matra", "Tyrrell" } }); racers.Add(new Racer() { FirstName = "Emerson", LastName = "Fittipaldi", Country = "Brazil", Starts = 143, Wins = 14, Years = new int[] { 1972, 1974 }, Cars = new string[] { "Lotus", "McLaren" } }); racers.Add(new Racer() { FirstName = "James", LastName = "Hunt", Country = "UK", Starts = 91, Wins = 10, Years = new int[] { 1976 }, Cars = new string[] { "McLaren" } }); racers.Add(new Racer() { FirstName = "Mario", LastName = "Andretti", Country = "USA", Starts = 128, Wins = 12, Years = new int[] { 1978 }, Cars = new string[] { "Lotus" } }); racers.Add(new Racer() { FirstName = "Jody", LastName = "Scheckter", Country = "South Africa", Starts = 112, Wins = 10, Years = new int[] { 1979 }, Cars = new string[] { "Ferrari" } }); racers.Add(new Racer() { FirstName = "Alan", LastName = "Jones", Country = "Australia", Starts = 115, Wins = 12, Years = new int[] { 1980 }, Cars = new string[] { "Williams" } }); racers.Add(new Racer() { FirstName = "Keke", LastName = "Rosberg", Country = "Finland", Starts = 114, Wins = 5, Years = new int[] { 1982 }, Cars = new string[] { "Williams" } }); racers.Add(new Racer() { FirstName = "Niki", LastName = "Lauda", Country = "Austria", Starts = 173, Wins = 25, Years = new int[] { 1975, 1977, 1984 }, Cars = new string[] { "Ferrari", "McLaren" } }); racers.Add(new Racer() { FirstName = "Nelson", LastName = "Piquet", Country = "Brazil", Starts = 204, Wins = 23, Years = new int[] { 1981, 1983, 1987 }, Cars = new string[] { "Brabham", "Williams" } }); racers.Add(new Racer() { FirstName = "Ayrton", LastName = "Senna", Country = "Brazil", Starts = 161, Wins = 41, Years = new int[] { 1988, 1990, 1991 }, Cars = new string[] { "McLaren" } }); racers.Add(new Racer() { FirstName = "Nigel", LastName = "Mansell", Country = "UK", Starts = 187, Wins = 31, Years = new int[] { 1992 }, Cars = new string[] { "Williams" } }); racers.Add(new Racer() { FirstName = "Alain", LastName = "Prost", Country = "France", Starts = 197, Wins = 51, Years = new int[] { 1985, 1986, 1989, 1993 }, Cars = new string[] { "McLaren", "Williams" } }); racers.Add(new Racer() { FirstName = "Damon", LastName = "Hill", Country = "UK", Starts = 114, Wins = 22, Years = new int[] { 1996 }, Cars = new string[] { "Williams" } }); racers.Add(new Racer() { FirstName = "Jacques", LastName = "Villeneuve", Country = "Canada", Starts = 165, Wins = 11, Years = new int[] { 1997 }, Cars = new string[] { "Williams" } }); racers.Add(new Racer() { FirstName = "Mika", LastName = "Hakkinen", Country = "Finland", Starts = 160, Wins = 20, Years = new int[] { 1998, 1999 }, Cars = new string[] { "McLaren" } }); racers.Add(new Racer() { FirstName = "Michael", LastName = "Schumacher", Country = "Germany", Starts = 250, Wins = 91, Years = new int[] { 1994, 1995, 2000, 2001, 2002, 2003, 2004 }, Cars = new string[] { "Benetton", "Ferrari" } }); racers.Add(new Racer() { FirstName = "Fernando", LastName = "Alonso", Country = "Spain", Starts = 105, Wins = 19, Years = new int[] { 2005, 2006 }, Cars = new string[] { "Renault" } }); racers.Add(new Racer() { FirstName = "Kimi", LastName = "Räikkönen", Country = "Finland", Starts = 122, Wins = 15, Years = new int[] { 2007 }, Cars = new string[] { "Ferrari" } }); return racers; } //返回车队冠军列表 public static List<Team> GetContructorChampions() { List<Team> teams = new List<Team>(20); teams.Add(new Team() { Name = "Vanwall", Years = new int[] { 1958 } }); teams.Add(new Team() { Name = "Cooper", Years = new int[] { 1959, 1960 } }); teams.Add(new Team() { Name = "Ferrari", Years = new int[] { 1961, 1964, 1975, 1976, 1977, 1979, 1982, 1983, 1999, 2000, 2001, 2002, 2003, 2004, 2007 } }); teams.Add(new Team() { Name = "BRM", Years = new int[] { 1962 } }); teams.Add(new Team() { Name = "Lotus", Years = new int[] { 1963, 1965, 1968, 1970, 1972, 1973, 1978 } }); teams.Add(new Team() { Name = "Brabham", Years = new int[] { 1966, 1967 } }); teams.Add(new Team() { Name = "Matra", Years = new int[] { 1969 } }); teams.Add(new Team() { Name = "Tyrrell", Years = new int[] { 1971 } }); teams.Add(new Team() { Name = "McLaren", Years = new int[] { 1974, 1984, 1985, 1988, 1989, 1990, 1991, 1998 } }); teams.Add(new Team() { Name = "Williams", Years = new int[] { 1980, 1981, 1986, 1987, 1992, 1993, 1994, 1996, 1997 } }); teams.Add(new Team() { Name = "Benetton", Years = new int[] { 1995 } }); teams.Add(new Team() { Name = "Renault", Years = new int[] { 2005, 2006 } }); return teams; } }

              一、筛选操作符

              where子句合并多个表达式。 根据条件返回匹配元素的集合IEnumerable。

              业务说明:找出赢得至少15场比赛的英国和奥地利赛车手。

              var racers = from r in Formula1.GetChampions() where r.Wins > 15 && (r.Country == "Brazil" || r.Country == "Austria") select r; foreach (var racer in racers) { Console.WriteLine("{0:A}", racer); }

              下面代码有Where扩展方法Where和Select调用。

              var racers = Formula1.GetChampions(). Where(r => r.Wins > 15 && (r.Country == "Brazil" || r.Country == "Austria")). Select(r => r);

              结果:

              //Niki Lauda, Austria; starts: 173, wins: 25
              //Nelson Piquet, Brazil; starts: 204, wins: 23
              //Ayrton Senna, Brazil; starts: 161, wins: 41

              1、索引器筛选

              索引是筛选器返回的每个结果的计数器。下面由Where扩展方法调用, 使用索引返回。

              业务说明:找出上述的、索引为偶数的赛车手

              var racers1 = Formula1.GetChampions() .Where((r, index)=> r.Wins > 15 && (r.Country == "Brazil" || r.Country == "Austria") && index % 2 != 0) .Select(r => r);

              结果:

              Nelson Piquet

              2、类型筛选OfType

              基于类型筛选,使用 OfType 扩展方法。

              业务说明:取出下面所有int类型的参数

              object[] data = { "one", 1, 2, "li" }; var query = data.OfType<int>(); foreach (var intValue in query) { Console.WriteLine("{0}", intValue); } //1 //2

              例2:取出下面racer类型的值

              IList mixedList = new ArrayList(); mixedList.Add( Formula1.GetChampions()[0]); mixedList.Add(Formula1.GetContructorChampions()[0]); mixedList.Add("Two"); mixedList.Add(3); var query = mixedList.OfType<Racer>(); foreach (var item in query) { Console.WriteLine("{0}", item); }

              二、投影操作符

              1、Select 子句

              将序列的每个元素经过lambda表达式处理后投影到一个新类型元素上。

              (与SelectMany不同在于,若单个元素投影到IEnumerable,Select不会对多个IEnumerable进行合并)

              用Select方法创建匿名类型

              var query2 = Formula1.GetChampions() .GroupBy(r => r.Country) .Select(g => new { Group = g, Count = g.Count() }) .OrderByDescending(g => g.Count) .ThenBy(g => g.Group.Key) .Where(g => g.Count > 1) .Select(g => new { Country = g.Group.Key, Count = g.Count }); foreach (var racer in query2) { Console.WriteLine("{0:A}", racer); }

              结果:

              { Country = UK, Count = 8 }
              { Country = Brazil, Count = 3 }
              { Country = Finland, Count = 3 }
              { Country = Australia, Count = 2 }
              { Country = Austria, Count = 2 }
              { Country = Italy, Count = 2 }
              { Country = USA, Count = 2 }

              相应的lambda表达式:

              var query3 = from r in Formula1.GetChampions() group r by r.Country into g let count=g.Count() orderby count descending, g.Key where count > 1 select new { Country = g.Key, Count = count }; foreach (var racer in query3) { Console.WriteLine("{0:A}", racer); }

              2、复合的From子句

              业务说明:筛选驾驶法拉利的所有冠军

              var ferrariDrivers = from r in Formula1.GetChampions() from c in r.Cars where c == "Ferrari" orderby r.LastName select r.FirstName + " " + r.LastName; foreach (var racer in ferrariDrivers) { Console.WriteLine("{0:A}", racer); }

              结果:

              Alberto Ascari
              Juan Manuel Fangio
              Mike Hawthorn
              Phil Hill
              Niki Lauda
              Kimi Räikkönen
              Jody Scheckter
              Michael Schumacher
              John Surtees

              C#编译器会把复合的from语句转换为SelectMany方法。

              var ferrariDrivers = Formula1.GetChampions() .SelectMany(r => r.Cars, (r, c) => new { Racer = r, Car = c }) .Where(r => r.Car == "Ferrari") .OrderBy(r => r.Racer.LastName) .Select(r => r.Racer.FirstName + " " + r.Racer.LastName);

              符合from子句,将子集合与复集合在同一个表平行展示。

              var ferrariDrivers = Formula1.GetChampions() .SelectMany(r => r.Cars, (r, c) => new { Racer = r, Car = c }) .Where(r => r.Racer.Country == "UK") .OrderBy(r => r.Racer.LastName) .ThenBy(r => r.Car) .Select(r => r); foreach (var racer in ferrariDrivers) { Console.WriteLine("{0:A}", racer + " :" + racer.Racer.Cars); }

              结果:

              { Racer = Jim Clark, Car = Lotus } :Lotus
              { Racer = Mike Hawthorn, Car = Ferrari } :Ferrari
              { Racer = Graham Hill, Car = BRM } :BRM
              { Racer = Graham Hill, Car = Lotus } :BRM
              { Racer = Damon Hill, Car = Williams } :Williams
              { Racer = James Hunt, Car = McLaren } :McLaren
              { Racer = Nigel Mansell, Car = Williams } :Williams
              { Racer = Jackie Stewart, Car = Matra } :Matra
              { Racer = Jackie Stewart, Car = Tyrrell } :Matra
              { Racer = John Surtees, Car = Ferrari } :Ferrari

              三、let子句

              上面的例子:

              var query8 = from r in Formula1.GetChampions() group r by r.Country into g orderby g.Count() descending, g.Key where g.Count() > 1 select new { Country = g.Key, Count = g.Count() };

              上面的分组查询Count方法调用了多次。使用let子句可以改变这种形式

              var query10 = from r in Formula1.GetChampions() group r by r.Country into g let count = g.Count() orderby count descending, g.Key where count > 1 select new { Country = g.Key, Count = count };

              四、排序操作符

              业务说明:来自英国的赛车手按照赢得比赛的次数进行降序排序

              您的问题似乎不完整,您是想询问关于C语言编程的某个具体问题吗?比如C语言的语法、编程技巧、项目开发等。请提供更具体的信息,这样我才能给出更准确的回答。

              var query6 = from r in Formula1.GetChampions() where r.Country == "UK" orderby r.Wins descending select r; foreach (var racer in query6) { Console.WriteLine("{0:A}", racer); }

              结果:

              Nigel Mansell, UK; starts: 187, wins: 31
              Jackie Stewart, UK; starts: 99, wins: 27
              Jim Clark, UK; starts: 72, wins: 25
              Damon Hill, UK; starts: 114, wins: 22
              Graham Hill, UK; starts: 176, wins: 14
              James Hunt, UK; starts: 91, wins: 10
              John Surtees, UK; starts: 111, wins: 6
              Mike Hawthorn, UK; starts: 45, wins: 3

              使用OrderBy(),OrderByDescending方式替换掉上面的写法:

              var racers2 = Formula1.GetChampions() .Where(r => r.Country == "UK") .OrderByDescending(r => r.Wins) .Select(r => r);

              使用ThenBy() 和 ThenByDescending() 方法继续排序进行二次排序

              业务说明:获取车手冠军列表,并依次按照Country升序、LastName降序、FirstName升序进行排序。扩展方法 Take 提取前面 10 个元素。

              // 查询表达式 var racers = (from r in Formula1.GetChampions() orderby r.Country, r.LastName descending, r.FirstName select r).Take(10); // 方法语法 var racers1 = Formula1.GetChampions() .OrderBy(r => r.Country) .ThenByDescending(r => r.LastName) .ThenBy(r => r.FirstName).Take(10); foreach (var racer in racers) { Console.WriteLine("{0:A}", racer); } //Juan Manuel Fangio, Argentina; starts: 51, wins: 24 //Alan Jones, Australia; starts: 115, wins: 12 //Jack Brabham, Australia; starts: 125, wins: 14 //Jochen Rindt, Austria; starts: 60, wins: 6 //Niki Lauda, Austria; starts: 173, wins: 25 //Ayrton Senna, Brazil; starts: 161, wins: 41 //Nelson Piquet, Brazil; starts: 204, wins: 23 //Emerson Fittipaldi, Brazil; starts: 143, wins: 14 //Jacques Villeneuve, Canada; starts: 165, wins: 11 //Keke Rosberg, Finland; starts: 114, wins: 5

              五、分组操作符

              根据一个关键字值对查询结果进行分组,使用 group 子句。

              子句 group r by r.Country into g 根据 Country 属性组合。并定义一个新的标识符g,它以后用于访问分组的结果信息。

              业务说明:列出每个国家的冠军数

              var countries = from r in Formula1.GetChampions() group r by r.Country into g orderby g.Count() descending, g.Key where g.Count() > 1 select new { Country = g.Key, Count = g.Count() }; foreach (var country in countries) { Console.WriteLine(format: "{0,-10} {1}", arg0: country.Country, arg1: country.Count); }

              结果:

              UK 8
              Brazil 3
              Finland 3
              Australia 2
              Austria 2
              Italy 2
              USA 2

              使用扩展方法,子句 group r by r.Country into g 解析为 GroupBy(r => r.Country) 返回分组序列。

              var countries = Formual.GetChampions() .GroupBy(r => r.Country) .OrderByDescending(g => g.Count()) .ThenBy(g => g.Key) .Where(g => g.Count() > 1) .Select(g => new { Country = g.Key, Count = g.Count() });

              返回值为 IEnumerable。

              1、对嵌套的对象分组

              分组的对象包含嵌套的序列,可以改变 select 子句创建的匿名类型。

              业务说明:分组查询每个国家获得冠军的赛车手人数,人数必须大于3,返回国家名称、国家赛车手冠军数量、赛车手名称。

              var query = from r in Formula1.GetChampions() group r by r.Country into g orderby g.Count() descending, g.Key where g.Count() >= 3 select new { Country = g.Key, count = g.Count(), RacerNickName = from r1 in g orderby r1.FirstName select r1.FirstName + " " + r1.LastName }; foreach (var g in query) { Console.WriteLine("{0:A}",g.Country+" "+g.count); foreach (var element in g.RacerNickName) { Console.WriteLine("---{0:A}",element); } }

              对应的扩展方法:

              var query1 = Formula1.GetChampions() .GroupBy(r => r.Country) .OrderByDescending(g => g.Count()) .ThenBy(g => g.Key) .Where(g => g.Count() >= 3) .Select(g => new { Country = g.Key, count = g.Count(), RacerNickName = g.OrderBy(r1 => r1.FirstName).Select(r1 => r1.FirstName + " " + r1.LastName) });

              结果:

              UK 8
              ---Damon Hill
              ---Graham Hill
              ---Jackie Stewart
              ---James Hunt
              ---Jim Clark
              ---John Surtees
              ---Mike Hawthorn
              ---Nigel Mansell
              Brazil 3
              ---Ayrton Senna
              ---Emerson Fittipaldi
              ---Nelson Piquet
              Finland 3
              ---Keke Rosberg
              ---Kimi Räikkönen
              ---Mika Hakkinen

              2、多字段分组

              var query = from r in Formula1.GetChampions() group r by new { r.Country, r.LastName } into g orderby g.Count() descending, g.Key.Country, g.Key.LastName where g.Count() >= 1 select new { MyGroup = g.Key, count = g.Count(), Racers = g }; foreach (var g in query) { Console.WriteLine("{0:A}", g.MyGroup + " : " + g.count); foreach (var element in g.Racers) { Console.WriteLine("---{0:A}", element); } }

              结果:

              { Country = UK, LastName = Hill } : 2
              ---Graham Hill, UK; starts: 176, wins: 14
              ---Damon Hill, UK; starts: 114, wins: 22
              { Country = Argentina, LastName = Fangio } : 1
              ---Juan Manuel Fangio, Argentina; starts: 51, wins: 24

              。。。

              3、分组后再每组里面仅取满足条件的行

              var query = from r in Formula1.GetChampions() group r by r.Country into g let maxId = g.Max(a => a.Wins) orderby g.Key where g.Count() >= 1 from row in g where row.Wins == maxId select row; foreach (var g in query) { Console.WriteLine("{0:A}", g); }

              到此这篇关于C#使用LINQ查询操作符的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持自由互联。

              本文共计3768个文字,预计阅读时间需要16分钟。

              您的问题似乎不完整,您是想询问关于C语言编程的某个具体问题吗?比如C语言的语法、编程技巧、项目开发等。请提供更具体的信息,这样我才能给出更准确的回答。

              目录+相关阅读+示例业务背景介绍+一、筛选操作符+结果:1、引⽤器筛选+2、类型筛选OfType+二、投影操作符+1、Select+子句+结果:对应的lambda表达式+2、复合的From子句+三、let子句+四、

              目录
              • 相关阅读
              • 示例业务背景介绍
              • 一、筛选操作符
                • 结果:
                • 1、索引器筛选
                • 2、类型筛选OfType
              • 二、投影操作符
                • 1、Select 子句
                  • 结果:
                  • 相应的lambda表达式:
                • 2、复合的From子句
                • 三、let子句
                  • 四、排序操作符
                    • 使用ThenBy() 和 ThenByDescending() 方法继续排序进行二次排序
                    • 五、分组操作符
                      • 1、对嵌套的对象分组
                        • 2、多字段分组
                          • 3、分组后再每组里面仅取满足条件的行

                          相关阅读

                          C#使用LINQ查询操作符实例代码(一)

                          C#使用LINQ查询操作符实例代码(二)

                          示例业务背景介绍

                          示例参考《C#高级编程(第六版)》LINQ章节(P267 - P296),进行改编。

                          打开示例代码我们看到:

                          1、Racer.cs车手冠军信息类

                          定义一级方程式世界车手冠军信息。

                          2、Team.cs车队冠军信息类

                          定义一级方程式世界车队冠军信息。

                          3、Formula1.cs 一级方程式类

                          包含两个重要静态方法:(F1是"Formula One"的缩写)

                          • GetChampions():返回一组车手列表。这个列表包含了1950到2007年之间的所有一级方程式世界车手冠军
                          • GetContructorChampions():返回一组车队列表。这个列表包含了1985到2007年之间的所有一级方程式世界车队冠军。

                          [Serializable] public class Racer : IComparable<Racer>, IFormattable, IEquatable<Racer> { public string FirstName { get; set; } public string LastName { get; set; } public int Wins { get; set; } public string Country { get; set; } public int Starts { get; set; } public string[] Cars { get; set; } public int[] Years { get; set; } public string ToString(string format, IFormatProvider formatProvider) { switch (format) { case null: case "N": return ToString(); case "F": return FirstName; case "L": return LastName; case "C": return Country; case "S": return Starts.ToString(); case "W": return Wins.ToString(); case "A": return String.Format("{0} {1}, {2}; starts: {3}, wins: {4}", FirstName, LastName, Country, Starts, Wins); default: throw new FormatException(String.Format( "Format {0} not supported", format)); } } public bool Equals(Racer other) { return this.FirstName == other.FirstName && this.LastName == other.LastName; } public int CompareTo(Racer other) { return this.LastName.CompareTo(other.LastName); } public string ToString(string format) { return ToString(format, null); } public override string ToString() { return String.Format("{0} {1}", FirstName, LastName); } } public class Team { public string Name { get; set; } public int[] Years { get; set; } } public class Formula1 { //返回车手冠军列表 public static List<Racer> GetChampions() { List<Racer> racers = new List<Racer>(40); racers.Add(new Racer() { FirstName = "Nino", LastName = "Farina", Country = "Italy", Starts = 33, Wins = 5, Years = new int[] { 1950 }, Cars = new string[] { "Alfa Romeo" } }); racers.Add(new Racer() { FirstName = "Alberto", LastName = "Ascari", Country = "Italy", Starts = 32, Wins = 10, Years = new int[] { 1952, 1953 }, Cars = new string[] { "Ferrari" } }); racers.Add(new Racer() { FirstName = "Juan Manuel", LastName = "Fangio", Country = "Argentina", Starts = 51, Wins = 24, Years = new int[] { 1951, 1954, 1955, 1956, 1957 }, Cars = new string[] { "Alfa Romeo", "Maserati", "Mercedes", "Ferrari" } }); racers.Add(new Racer() { FirstName = "Mike", LastName = "Hawthorn", Country = "UK", Starts = 45, Wins = 3, Years = new int[] { 1958 }, Cars = new string[] { "Ferrari" } }); racers.Add(new Racer() { FirstName = "Phil", LastName = "Hill", Country = "USA", Starts = 48, Wins = 3, Years = new int[] { 1961 }, Cars = new string[] { "Ferrari" } }); racers.Add(new Racer() { FirstName = "John", LastName = "Surtees", Country = "UK", Starts = 111, Wins = 6, Years = new int[] { 1964 }, Cars = new string[] { "Ferrari" } }); racers.Add(new Racer() { FirstName = "Jim", LastName = "Clark", Country = "UK", Starts = 72, Wins = 25, Years = new int[] { 1963, 1965 }, Cars = new string[] { "Lotus" } }); racers.Add(new Racer() { FirstName = "Jack", LastName = "Brabham", Country = "Australia", Starts = 125, Wins = 14, Years = new int[] { 1959, 1960, 1966 }, Cars = new string[] { "Cooper", "Brabham" } }); racers.Add(new Racer() { FirstName = "Denny", LastName = "Hulme", Country = "New Zealand", Starts = 112, Wins = 8, Years = new int[] { 1967 }, Cars = new string[] { "Brabham" } }); racers.Add(new Racer() { FirstName = "Graham", LastName = "Hill", Country = "UK", Starts = 176, Wins = 14, Years = new int[] { 1962, 1968 }, Cars = new string[] { "BRM", "Lotus" } }); racers.Add(new Racer() { FirstName = "Jochen", LastName = "Rindt", Country = "Austria", Starts = 60, Wins = 6, Years = new int[] { 1970 }, Cars = new string[] { "Lotus" } }); racers.Add(new Racer() { FirstName = "Jackie", LastName = "Stewart", Country = "UK", Starts = 99, Wins = 27, Years = new int[] { 1969, 1971, 1973 }, Cars = new string[] { "Matra", "Tyrrell" } }); racers.Add(new Racer() { FirstName = "Emerson", LastName = "Fittipaldi", Country = "Brazil", Starts = 143, Wins = 14, Years = new int[] { 1972, 1974 }, Cars = new string[] { "Lotus", "McLaren" } }); racers.Add(new Racer() { FirstName = "James", LastName = "Hunt", Country = "UK", Starts = 91, Wins = 10, Years = new int[] { 1976 }, Cars = new string[] { "McLaren" } }); racers.Add(new Racer() { FirstName = "Mario", LastName = "Andretti", Country = "USA", Starts = 128, Wins = 12, Years = new int[] { 1978 }, Cars = new string[] { "Lotus" } }); racers.Add(new Racer() { FirstName = "Jody", LastName = "Scheckter", Country = "South Africa", Starts = 112, Wins = 10, Years = new int[] { 1979 }, Cars = new string[] { "Ferrari" } }); racers.Add(new Racer() { FirstName = "Alan", LastName = "Jones", Country = "Australia", Starts = 115, Wins = 12, Years = new int[] { 1980 }, Cars = new string[] { "Williams" } }); racers.Add(new Racer() { FirstName = "Keke", LastName = "Rosberg", Country = "Finland", Starts = 114, Wins = 5, Years = new int[] { 1982 }, Cars = new string[] { "Williams" } }); racers.Add(new Racer() { FirstName = "Niki", LastName = "Lauda", Country = "Austria", Starts = 173, Wins = 25, Years = new int[] { 1975, 1977, 1984 }, Cars = new string[] { "Ferrari", "McLaren" } }); racers.Add(new Racer() { FirstName = "Nelson", LastName = "Piquet", Country = "Brazil", Starts = 204, Wins = 23, Years = new int[] { 1981, 1983, 1987 }, Cars = new string[] { "Brabham", "Williams" } }); racers.Add(new Racer() { FirstName = "Ayrton", LastName = "Senna", Country = "Brazil", Starts = 161, Wins = 41, Years = new int[] { 1988, 1990, 1991 }, Cars = new string[] { "McLaren" } }); racers.Add(new Racer() { FirstName = "Nigel", LastName = "Mansell", Country = "UK", Starts = 187, Wins = 31, Years = new int[] { 1992 }, Cars = new string[] { "Williams" } }); racers.Add(new Racer() { FirstName = "Alain", LastName = "Prost", Country = "France", Starts = 197, Wins = 51, Years = new int[] { 1985, 1986, 1989, 1993 }, Cars = new string[] { "McLaren", "Williams" } }); racers.Add(new Racer() { FirstName = "Damon", LastName = "Hill", Country = "UK", Starts = 114, Wins = 22, Years = new int[] { 1996 }, Cars = new string[] { "Williams" } }); racers.Add(new Racer() { FirstName = "Jacques", LastName = "Villeneuve", Country = "Canada", Starts = 165, Wins = 11, Years = new int[] { 1997 }, Cars = new string[] { "Williams" } }); racers.Add(new Racer() { FirstName = "Mika", LastName = "Hakkinen", Country = "Finland", Starts = 160, Wins = 20, Years = new int[] { 1998, 1999 }, Cars = new string[] { "McLaren" } }); racers.Add(new Racer() { FirstName = "Michael", LastName = "Schumacher", Country = "Germany", Starts = 250, Wins = 91, Years = new int[] { 1994, 1995, 2000, 2001, 2002, 2003, 2004 }, Cars = new string[] { "Benetton", "Ferrari" } }); racers.Add(new Racer() { FirstName = "Fernando", LastName = "Alonso", Country = "Spain", Starts = 105, Wins = 19, Years = new int[] { 2005, 2006 }, Cars = new string[] { "Renault" } }); racers.Add(new Racer() { FirstName = "Kimi", LastName = "Räikkönen", Country = "Finland", Starts = 122, Wins = 15, Years = new int[] { 2007 }, Cars = new string[] { "Ferrari" } }); return racers; } //返回车队冠军列表 public static List<Team> GetContructorChampions() { List<Team> teams = new List<Team>(20); teams.Add(new Team() { Name = "Vanwall", Years = new int[] { 1958 } }); teams.Add(new Team() { Name = "Cooper", Years = new int[] { 1959, 1960 } }); teams.Add(new Team() { Name = "Ferrari", Years = new int[] { 1961, 1964, 1975, 1976, 1977, 1979, 1982, 1983, 1999, 2000, 2001, 2002, 2003, 2004, 2007 } }); teams.Add(new Team() { Name = "BRM", Years = new int[] { 1962 } }); teams.Add(new Team() { Name = "Lotus", Years = new int[] { 1963, 1965, 1968, 1970, 1972, 1973, 1978 } }); teams.Add(new Team() { Name = "Brabham", Years = new int[] { 1966, 1967 } }); teams.Add(new Team() { Name = "Matra", Years = new int[] { 1969 } }); teams.Add(new Team() { Name = "Tyrrell", Years = new int[] { 1971 } }); teams.Add(new Team() { Name = "McLaren", Years = new int[] { 1974, 1984, 1985, 1988, 1989, 1990, 1991, 1998 } }); teams.Add(new Team() { Name = "Williams", Years = new int[] { 1980, 1981, 1986, 1987, 1992, 1993, 1994, 1996, 1997 } }); teams.Add(new Team() { Name = "Benetton", Years = new int[] { 1995 } }); teams.Add(new Team() { Name = "Renault", Years = new int[] { 2005, 2006 } }); return teams; } }

                          一、筛选操作符

                          where子句合并多个表达式。 根据条件返回匹配元素的集合IEnumerable。

                          业务说明:找出赢得至少15场比赛的英国和奥地利赛车手。

                          var racers = from r in Formula1.GetChampions() where r.Wins > 15 && (r.Country == "Brazil" || r.Country == "Austria") select r; foreach (var racer in racers) { Console.WriteLine("{0:A}", racer); }

                          下面代码有Where扩展方法Where和Select调用。

                          var racers = Formula1.GetChampions(). Where(r => r.Wins > 15 && (r.Country == "Brazil" || r.Country == "Austria")). Select(r => r);

                          结果:

                          //Niki Lauda, Austria; starts: 173, wins: 25
                          //Nelson Piquet, Brazil; starts: 204, wins: 23
                          //Ayrton Senna, Brazil; starts: 161, wins: 41

                          1、索引器筛选

                          索引是筛选器返回的每个结果的计数器。下面由Where扩展方法调用, 使用索引返回。

                          业务说明:找出上述的、索引为偶数的赛车手

                          var racers1 = Formula1.GetChampions() .Where((r, index)=> r.Wins > 15 && (r.Country == "Brazil" || r.Country == "Austria") && index % 2 != 0) .Select(r => r);

                          结果:

                          Nelson Piquet

                          2、类型筛选OfType

                          基于类型筛选,使用 OfType 扩展方法。

                          业务说明:取出下面所有int类型的参数

                          object[] data = { "one", 1, 2, "li" }; var query = data.OfType<int>(); foreach (var intValue in query) { Console.WriteLine("{0}", intValue); } //1 //2

                          例2:取出下面racer类型的值

                          IList mixedList = new ArrayList(); mixedList.Add( Formula1.GetChampions()[0]); mixedList.Add(Formula1.GetContructorChampions()[0]); mixedList.Add("Two"); mixedList.Add(3); var query = mixedList.OfType<Racer>(); foreach (var item in query) { Console.WriteLine("{0}", item); }

                          二、投影操作符

                          1、Select 子句

                          将序列的每个元素经过lambda表达式处理后投影到一个新类型元素上。

                          (与SelectMany不同在于,若单个元素投影到IEnumerable,Select不会对多个IEnumerable进行合并)

                          用Select方法创建匿名类型

                          var query2 = Formula1.GetChampions() .GroupBy(r => r.Country) .Select(g => new { Group = g, Count = g.Count() }) .OrderByDescending(g => g.Count) .ThenBy(g => g.Group.Key) .Where(g => g.Count > 1) .Select(g => new { Country = g.Group.Key, Count = g.Count }); foreach (var racer in query2) { Console.WriteLine("{0:A}", racer); }

                          结果:

                          { Country = UK, Count = 8 }
                          { Country = Brazil, Count = 3 }
                          { Country = Finland, Count = 3 }
                          { Country = Australia, Count = 2 }
                          { Country = Austria, Count = 2 }
                          { Country = Italy, Count = 2 }
                          { Country = USA, Count = 2 }

                          相应的lambda表达式:

                          var query3 = from r in Formula1.GetChampions() group r by r.Country into g let count=g.Count() orderby count descending, g.Key where count > 1 select new { Country = g.Key, Count = count }; foreach (var racer in query3) { Console.WriteLine("{0:A}", racer); }

                          2、复合的From子句

                          业务说明:筛选驾驶法拉利的所有冠军

                          var ferrariDrivers = from r in Formula1.GetChampions() from c in r.Cars where c == "Ferrari" orderby r.LastName select r.FirstName + " " + r.LastName; foreach (var racer in ferrariDrivers) { Console.WriteLine("{0:A}", racer); }

                          结果:

                          Alberto Ascari
                          Juan Manuel Fangio
                          Mike Hawthorn
                          Phil Hill
                          Niki Lauda
                          Kimi Räikkönen
                          Jody Scheckter
                          Michael Schumacher
                          John Surtees

                          C#编译器会把复合的from语句转换为SelectMany方法。

                          var ferrariDrivers = Formula1.GetChampions() .SelectMany(r => r.Cars, (r, c) => new { Racer = r, Car = c }) .Where(r => r.Car == "Ferrari") .OrderBy(r => r.Racer.LastName) .Select(r => r.Racer.FirstName + " " + r.Racer.LastName);

                          符合from子句,将子集合与复集合在同一个表平行展示。

                          var ferrariDrivers = Formula1.GetChampions() .SelectMany(r => r.Cars, (r, c) => new { Racer = r, Car = c }) .Where(r => r.Racer.Country == "UK") .OrderBy(r => r.Racer.LastName) .ThenBy(r => r.Car) .Select(r => r); foreach (var racer in ferrariDrivers) { Console.WriteLine("{0:A}", racer + " :" + racer.Racer.Cars); }

                          结果:

                          { Racer = Jim Clark, Car = Lotus } :Lotus
                          { Racer = Mike Hawthorn, Car = Ferrari } :Ferrari
                          { Racer = Graham Hill, Car = BRM } :BRM
                          { Racer = Graham Hill, Car = Lotus } :BRM
                          { Racer = Damon Hill, Car = Williams } :Williams
                          { Racer = James Hunt, Car = McLaren } :McLaren
                          { Racer = Nigel Mansell, Car = Williams } :Williams
                          { Racer = Jackie Stewart, Car = Matra } :Matra
                          { Racer = Jackie Stewart, Car = Tyrrell } :Matra
                          { Racer = John Surtees, Car = Ferrari } :Ferrari

                          三、let子句

                          上面的例子:

                          var query8 = from r in Formula1.GetChampions() group r by r.Country into g orderby g.Count() descending, g.Key where g.Count() > 1 select new { Country = g.Key, Count = g.Count() };

                          上面的分组查询Count方法调用了多次。使用let子句可以改变这种形式

                          var query10 = from r in Formula1.GetChampions() group r by r.Country into g let count = g.Count() orderby count descending, g.Key where count > 1 select new { Country = g.Key, Count = count };

                          四、排序操作符

                          业务说明:来自英国的赛车手按照赢得比赛的次数进行降序排序

                          您的问题似乎不完整,您是想询问关于C语言编程的某个具体问题吗?比如C语言的语法、编程技巧、项目开发等。请提供更具体的信息,这样我才能给出更准确的回答。

                          var query6 = from r in Formula1.GetChampions() where r.Country == "UK" orderby r.Wins descending select r; foreach (var racer in query6) { Console.WriteLine("{0:A}", racer); }

                          结果:

                          Nigel Mansell, UK; starts: 187, wins: 31
                          Jackie Stewart, UK; starts: 99, wins: 27
                          Jim Clark, UK; starts: 72, wins: 25
                          Damon Hill, UK; starts: 114, wins: 22
                          Graham Hill, UK; starts: 176, wins: 14
                          James Hunt, UK; starts: 91, wins: 10
                          John Surtees, UK; starts: 111, wins: 6
                          Mike Hawthorn, UK; starts: 45, wins: 3

                          使用OrderBy(),OrderByDescending方式替换掉上面的写法:

                          var racers2 = Formula1.GetChampions() .Where(r => r.Country == "UK") .OrderByDescending(r => r.Wins) .Select(r => r);

                          使用ThenBy() 和 ThenByDescending() 方法继续排序进行二次排序

                          业务说明:获取车手冠军列表,并依次按照Country升序、LastName降序、FirstName升序进行排序。扩展方法 Take 提取前面 10 个元素。

                          // 查询表达式 var racers = (from r in Formula1.GetChampions() orderby r.Country, r.LastName descending, r.FirstName select r).Take(10); // 方法语法 var racers1 = Formula1.GetChampions() .OrderBy(r => r.Country) .ThenByDescending(r => r.LastName) .ThenBy(r => r.FirstName).Take(10); foreach (var racer in racers) { Console.WriteLine("{0:A}", racer); } //Juan Manuel Fangio, Argentina; starts: 51, wins: 24 //Alan Jones, Australia; starts: 115, wins: 12 //Jack Brabham, Australia; starts: 125, wins: 14 //Jochen Rindt, Austria; starts: 60, wins: 6 //Niki Lauda, Austria; starts: 173, wins: 25 //Ayrton Senna, Brazil; starts: 161, wins: 41 //Nelson Piquet, Brazil; starts: 204, wins: 23 //Emerson Fittipaldi, Brazil; starts: 143, wins: 14 //Jacques Villeneuve, Canada; starts: 165, wins: 11 //Keke Rosberg, Finland; starts: 114, wins: 5

                          五、分组操作符

                          根据一个关键字值对查询结果进行分组,使用 group 子句。

                          子句 group r by r.Country into g 根据 Country 属性组合。并定义一个新的标识符g,它以后用于访问分组的结果信息。

                          业务说明:列出每个国家的冠军数

                          var countries = from r in Formula1.GetChampions() group r by r.Country into g orderby g.Count() descending, g.Key where g.Count() > 1 select new { Country = g.Key, Count = g.Count() }; foreach (var country in countries) { Console.WriteLine(format: "{0,-10} {1}", arg0: country.Country, arg1: country.Count); }

                          结果:

                          UK 8
                          Brazil 3
                          Finland 3
                          Australia 2
                          Austria 2
                          Italy 2
                          USA 2

                          使用扩展方法,子句 group r by r.Country into g 解析为 GroupBy(r => r.Country) 返回分组序列。

                          var countries = Formual.GetChampions() .GroupBy(r => r.Country) .OrderByDescending(g => g.Count()) .ThenBy(g => g.Key) .Where(g => g.Count() > 1) .Select(g => new { Country = g.Key, Count = g.Count() });

                          返回值为 IEnumerable。

                          1、对嵌套的对象分组

                          分组的对象包含嵌套的序列,可以改变 select 子句创建的匿名类型。

                          业务说明:分组查询每个国家获得冠军的赛车手人数,人数必须大于3,返回国家名称、国家赛车手冠军数量、赛车手名称。

                          var query = from r in Formula1.GetChampions() group r by r.Country into g orderby g.Count() descending, g.Key where g.Count() >= 3 select new { Country = g.Key, count = g.Count(), RacerNickName = from r1 in g orderby r1.FirstName select r1.FirstName + " " + r1.LastName }; foreach (var g in query) { Console.WriteLine("{0:A}",g.Country+" "+g.count); foreach (var element in g.RacerNickName) { Console.WriteLine("---{0:A}",element); } }

                          对应的扩展方法:

                          var query1 = Formula1.GetChampions() .GroupBy(r => r.Country) .OrderByDescending(g => g.Count()) .ThenBy(g => g.Key) .Where(g => g.Count() >= 3) .Select(g => new { Country = g.Key, count = g.Count(), RacerNickName = g.OrderBy(r1 => r1.FirstName).Select(r1 => r1.FirstName + " " + r1.LastName) });

                          结果:

                          UK 8
                          ---Damon Hill
                          ---Graham Hill
                          ---Jackie Stewart
                          ---James Hunt
                          ---Jim Clark
                          ---John Surtees
                          ---Mike Hawthorn
                          ---Nigel Mansell
                          Brazil 3
                          ---Ayrton Senna
                          ---Emerson Fittipaldi
                          ---Nelson Piquet
                          Finland 3
                          ---Keke Rosberg
                          ---Kimi Räikkönen
                          ---Mika Hakkinen

                          2、多字段分组

                          var query = from r in Formula1.GetChampions() group r by new { r.Country, r.LastName } into g orderby g.Count() descending, g.Key.Country, g.Key.LastName where g.Count() >= 1 select new { MyGroup = g.Key, count = g.Count(), Racers = g }; foreach (var g in query) { Console.WriteLine("{0:A}", g.MyGroup + " : " + g.count); foreach (var element in g.Racers) { Console.WriteLine("---{0:A}", element); } }

                          结果:

                          { Country = UK, LastName = Hill } : 2
                          ---Graham Hill, UK; starts: 176, wins: 14
                          ---Damon Hill, UK; starts: 114, wins: 22
                          { Country = Argentina, LastName = Fangio } : 1
                          ---Juan Manuel Fangio, Argentina; starts: 51, wins: 24

                          。。。

                          3、分组后再每组里面仅取满足条件的行

                          var query = from r in Formula1.GetChampions() group r by r.Country into g let maxId = g.Max(a => a.Wins) orderby g.Key where g.Count() >= 1 from row in g where row.Wins == maxId select row; foreach (var g in query) { Console.WriteLine("{0:A}", g); }

                          到此这篇关于C#使用LINQ查询操作符的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持自由互联。