首页 > 代码库 > 第十一章 LINQ
第十一章 LINQ
DataLib
using System; using System.Collections.Generic; namespace Wrox.ProCSharp.LINQ { [Serializable] public class Team { public Team(string name, params int[] years) { this.Name = name; this.Years = new List<int>(years); } public string Name { get; private set; } public IEnumerable<int> Years { get; private set; } } }
using System; using System.Collections.Generic; namespace Wrox.ProCSharp.LINQ { [Serializable] public class Racer : IComparable<Racer>, IFormattable { public Racer(string firstName, string lastName, string country, int starts, int wins) : this(firstName, lastName, country, starts, wins, null, null) { } public Racer(string firstName, string lastName, string country, int starts, int wins, IEnumerable<int> years, IEnumerable<string> cars) { this.FirstName = firstName; this.LastName = lastName; this.Country = country; this.Starts = starts; this.Wins = wins; this.Years = new List<int>(years); this.Cars = new List<string>(cars); } public string FirstName { get; set; } public string LastName { get; set; } public string Country { get; set; } public int Wins { get; set; } public int Starts { get; set; } public IEnumerable<string> Cars { get; private set; } public IEnumerable<int> Years { get; private set; } public override string ToString() { return String.Format("{0} {1}", FirstName, LastName); } public int CompareTo(Racer other) { if (other == null) return -1; return string.Compare(this.LastName, other.LastName); } public string ToString(string format) { return ToString(format, null); } 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)); } } } }
using System.Collections.Generic; namespace Wrox.ProCSharp.LINQ { public static class Formula1 { private static List<Racer> racers; public static IList<Racer> GetChampions() { if (racers == null) { racers = new List<Racer>(40); racers.Add(new Racer("Nino", "Farina", "Italy", 33, 5, new int[] { 1950 }, new string[] { "Alfa Romeo" })); racers.Add(new Racer("Alberto", "Ascari", "Italy", 32, 10, new int[] { 1952, 1953 }, new string[] { "Ferrari" })); racers.Add(new Racer("Juan Manuel", "Fangio", "Argentina", 51, 24, new int[] { 1951, 1954, 1955, 1956, 1957 }, new string[] { "Alfa Romeo", "Maserati", "Mercedes", "Ferrari" })); racers.Add(new Racer("Mike", "Hawthorn", "UK", 45, 3, new int[] { 1958 }, new string[] { "Ferrari" })); racers.Add(new Racer("Phil", "Hill", "USA", 48, 3, new int[] { 1961 }, new string[] { "Ferrari" })); racers.Add(new Racer("John", "Surtees", "UK", 111, 6, new int[] { 1964 }, new string[] { "Ferrari" })); racers.Add(new Racer("Jim", "Clark", "UK", 72, 25, new int[] { 1963, 1965 }, new string[] { "Lotus" })); racers.Add(new Racer("Jack", "Brabham", "Australia", 125, 14, new int[] { 1959, 1960, 1966 }, new string[] { "Cooper", "Brabham" })); racers.Add(new Racer("Denny", "Hulme", "New Zealand", 112, 8, new int[] { 1967 }, new string[] { "Brabham" })); racers.Add(new Racer("Graham", "Hill", "UK", 176, 14, new int[] { 1962, 1968 }, new string[] { "BRM", "Lotus" })); racers.Add(new Racer("Jochen", "Rindt", "Austria", 60, 6, new int[] { 1970 }, new string[] { "Lotus" })); racers.Add(new Racer("Jackie", "Stewart", "UK", 99, 27, new int[] { 1969, 1971, 1973 }, new string[] { "Matra", "Tyrrell" })); racers.Add(new Racer("Emerson", "Fittipaldi", "Brazil", 143, 14, new int[] { 1972, 1974 }, new string[] { "Lotus", "McLaren" })); racers.Add(new Racer("James", "Hunt", "UK", 91, 10, new int[] { 1976 }, new string[] { "McLaren" })); racers.Add(new Racer("Mario", "Andretti", "USA", 128, 12, new int[] { 1978 }, new string[] { "Lotus" })); racers.Add(new Racer("Jody", "Scheckter", "South Africa", 112, 10, new int[] { 1979 }, new string[] { "Ferrari" })); racers.Add(new Racer("Alan", "Jones", "Australia", 115, 12, new int[] { 1980 }, new string[] { "Williams" })); racers.Add(new Racer("Keke", "Rosberg", "Finland", 114, 5, new int[] { 1982 }, new string[] { "Williams" })); racers.Add(new Racer("Niki", "Lauda", "Austria", 173, 25, new int[] { 1975, 1977, 1984 }, new string[] { "Ferrari", "McLaren" })); racers.Add(new Racer("Nelson", "Piquet", "Brazil", 204, 23, new int[] { 1981, 1983, 1987 }, new string[] { "Brabham", "Williams" })); racers.Add(new Racer("Ayrton", "Senna", "Brazil", 161, 41, new int[] { 1988, 1990, 1991 }, new string[] { "McLaren" })); racers.Add(new Racer("Nigel", "Mansell", "UK", 187, 31, new int[] { 1992 }, new string[] { "Williams" })); racers.Add(new Racer("Alain", "Prost", "France", 197, 51, new int[] { 1985, 1986, 1989, 1993 }, new string[] { "McLaren", "Williams" })); racers.Add(new Racer("Damon", "Hill", "UK", 114, 22, new int[] { 1996 }, new string[] { "Williams" })); racers.Add(new Racer("Jacques", "Villeneuve", "Canada", 165, 11, new int[] { 1997 }, new string[] { "Williams" })); racers.Add(new Racer("Mika", "Hakkinen", "Finland", 160, 20, new int[] { 1998, 1999 }, new string[] { "McLaren" })); racers.Add(new Racer("Michael", "Schumacher", "Germany", 287, 91, new int[] { 1994, 1995, 2000, 2001, 2002, 2003, 2004 }, new string[] { "Benetton", "Ferrari" })); racers.Add(new Racer("Fernando", "Alonso", "Spain", 177, 27, new int[] { 2005, 2006 }, new string[] { "Renault" })); racers.Add(new Racer("Kimi", "R?ikk?nen", "Finland", 148, 17, new int[] { 2007 }, new string[] { "Ferrari" })); racers.Add(new Racer("Lewis", "Hamilton", "UK", 90, 17, new int[] { 2008 }, new string[] { "McLaren" })); racers.Add(new Racer("Jenson", "Button", "UK", 208, 12, new int[] { 2009 }, new string[] { "Brawn GP" })); racers.Add(new Racer("Sebastian", "Vettel", "Germany", 81, 21, new int[] { 2010, 2011 }, new string[] { "Red Bull Racing" })); } return racers; } private static List<Team> teams; public static IList<Team> GetContructorChampions() { if (teams == null) { teams = new List<Team>() { new Team("Vanwall", 1958), new Team("Cooper", 1959, 1960), new Team("Ferrari", 1961, 1964, 1975, 1976, 1977, 1979, 1982, 1983, 1999, 2000, 2001, 2002, 2003, 2004, 2007, 2008), new Team("BRM", 1962), new Team("Lotus", 1963, 1965, 1968, 1970, 1972, 1973, 1978), new Team("Brabham", 1966, 1967), new Team("Matra", 1969), new Team("Tyrrell", 1971), new Team("McLaren", 1974, 1984, 1985, 1988, 1989, 1990, 1991, 1998), new Team("Williams", 1980, 1981, 1986, 1987, 1992, 1993, 1994, 1996, 1997), new Team("Benetton", 1995), new Team("Renault", 2005, 2006 ), new Team("Brawn GP", 2009), new Team("Red Bull Racing", 2010, 2011) }; } return teams; } private static List<Championship> championships; public static IEnumerable<Championship> GetChampionships() { if (championships == null) { championships = new List<Championship>(); championships.Add(new Championship { Year = 1950, First = "Nino Farina", Second = "Juan Manuel Fangio", Third = "Luigi Fagioli" }); championships.Add(new Championship { Year = 1951, First = "Juan Manuel Fangio", Second = "Alberto Ascari", Third = "Froilan Gonzalez" }); championships.Add(new Championship { Year = 1952, First = "Alberto Ascari", Second = "Nino Farina", Third = "Piero Taruffi" }); championships.Add(new Championship { Year = 1953, First = "Alberto Ascari", Second = "Juan Manuel Fangio", Third = "Nino Farina" }); championships.Add(new Championship { Year = 1954, First = "Juan Manuel Fangio", Second = "Froilan Gonzalez", Third = "Mike Hawthorn" }); championships.Add(new Championship { Year = 1955, First = "Juan Manuel Fangio", Second = "Stirling Moss", Third = "Eugenio Castellotti" }); championships.Add(new Championship { Year = 1956, First = "Juan Manuel Fangio", Second = "Stirling Moss", Third = "Peter Collins" }); championships.Add(new Championship { Year = 1957, First = "Juan Manuel Fangio", Second = "Stirling Moss", Third = "Luigi Musso" }); championships.Add(new Championship { Year = 1958, First = "Mike Hawthorn", Second = "Stirling Moss", Third = "Tony Brooks" }); championships.Add(new Championship { Year = 1959, First = "Jack Brabham", Second = "Tony Brooks", Third = "Stirling Moss" }); championships.Add(new Championship { Year = 1960, First = "Jack Brabham", Second = "Bruce McLaren", Third = "Stirling Moss" }); championships.Add(new Championship { Year = 1961, First = "Phil Hill", Second = "Wolfgang von Trips", Third = "Stirling Moss" }); championships.Add(new Championship { Year = 1962, First = "Graham Hill", Second = "Jim Clark", Third = "Bruce McLaren" }); championships.Add(new Championship { Year = 1963, First = "Jim Clark", Second = "Graham Hill", Third = "Richie Ginther" }); championships.Add(new Championship { Year = 1964, First = "John Surtees", Second = "Graham Hill", Third = "Jim Clark" }); championships.Add(new Championship { Year = 1965, First = "Jim Clark", Second = "Graham Hill", Third = "Jackie Stewart" }); championships.Add(new Championship { Year = 1966, First = "Jack Brabham", Second = "John Surtees", Third = "Jochen Rindt" }); championships.Add(new Championship { Year = 1967, First = "Dennis Hulme", Second = "Jack Brabham", Third = "Jim Clark" }); championships.Add(new Championship { Year = 1968, First = "Graham Hill", Second = "Jackie Stewart", Third = "Dennis Hulme" }); championships.Add(new Championship { Year = 1969, First = "Jackie Stewart", Second = "Jackie Ickx", Third = "Bruce McLaren" }); championships.Add(new Championship { Year = 1970, First = "Jochen Rindt", Second = "Jackie Ickx", Third = "Clay Regazzoni" }); championships.Add(new Championship { Year = 1971, First = "Jackie Stewart", Second = "Ronnie Peterson", Third = "Francois Cevert" }); championships.Add(new Championship { Year = 1972, First = "Emerson Fittipaldi", Second = "Jackie Stewart", Third = "Dennis Hulme" }); championships.Add(new Championship { Year = 1973, First = "Jackie Stewart", Second = "Emerson Fittipaldi", Third = "Ronnie Peterson" }); championships.Add(new Championship { Year = 1974, First = "Emerson Fittipaldi", Second = "Clay Regazzoni", Third = "Jody Scheckter" }); championships.Add(new Championship { Year = 1975, First = "Niki Lauda", Second = "Emerson Fittipaldi", Third = "Carlos Reutemann" }); championships.Add(new Championship { Year = 1976, First = "James Hunt", Second = "Niki Lauda", Third = "Jody Scheckter" }); championships.Add(new Championship { Year = 1977, First = "Niki Lauda", Second = "Jody Scheckter", Third = "Mario Andretti" }); championships.Add(new Championship { Year = 1978, First = "Mario Andretti", Second = "Ronnie Peterson", Third = "Carlos Reutemann" }); championships.Add(new Championship { Year = 1979, First = "Jody Scheckter", Second = "Gilles Villeneuve", Third = "Alan Jones" }); championships.Add(new Championship { Year = 1980, First = "Alan Jones", Second = "Nelson Piquet", Third = "Carlos Reutemann" }); championships.Add(new Championship { Year = 1981, First = "Nelson Piquet", Second = "Carlos Reutemann", Third = "Alan Jones" }); championships.Add(new Championship { Year = 1982, First = "Keke Rosberg", Second = "Didier Pironi", Third = "John Watson" }); championships.Add(new Championship { Year = 1983, First = "Nelson Piquet", Second = "Alain Prost", Third = "Rene Arnoux" }); championships.Add(new Championship { Year = 1984, First = "Niki Lauda", Second = "Alain Prost", Third = "Elio de Angelis" }); championships.Add(new Championship { Year = 1985, First = "Alain Prost", Second = "Michele Alboreto", Third = "Keke Rosberg" }); championships.Add(new Championship { Year = 1986, First = "Alain Prost", Second = "Nigel Mansell", Third = "Nelson Piquet" }); championships.Add(new Championship { Year = 1987, First = "Nelson Piquet", Second = "Nigel Mansell", Third = "Ayrton Senna" }); championships.Add(new Championship { Year = 1988, First = "Ayrton Senna", Second = "Alain Prost", Third = "Gerhard Berger" }); championships.Add(new Championship { Year = 1989, First = "Alain Prost", Second = "Ayrton Senna", Third = "Riccardo Patrese" }); championships.Add(new Championship { Year = 1990, First = "Ayrton Senna", Second = "Alain Prost", Third = "Nelson Piquet" }); championships.Add(new Championship { Year = 1991, First = "Ayrton Senna", Second = "Nigel Mansell", Third = "Riccardo Patrese" }); championships.Add(new Championship { Year = 1992, First = "Nigel Mansell", Second = "Riccardo Patrese", Third = "Michael Schumacher" }); championships.Add(new Championship { Year = 1993, First = "Alain Prost", Second = "Ayrton Senna", Third = "Damon Hill" }); championships.Add(new Championship { Year = 1994, First = "Michael Schumacher", Second = "Damon Hill", Third = "Gerhard Berger" }); championships.Add(new Championship { Year = 1995, First = "Michael Schumacher", Second = "Damon Hill", Third = "David Coulthard" }); championships.Add(new Championship { Year = 1996, First = "Damon Hill", Second = "Jacques Villeneuve", Third = "Michael Schumacher" }); championships.Add(new Championship { Year = 1997, First = "Jacques Villeneuve", Second = "Heinz-Harald Frentzen", Third = "David Coulthard" }); championships.Add(new Championship { Year = 1998, First = "Mika Hakkinen", Second = "Michael Schumacher", Third = "David Coulthard" }); championships.Add(new Championship { Year = 1999, First = "Mika Hakkinen", Second = "Eddie Irvine", Third = "Heinz-Harald Frentzen" }); championships.Add(new Championship { Year = 2000, First = "Michael Schumacher", Second = "Mika Hakkinen", Third = "David Coulthard" }); championships.Add(new Championship { Year = 2001, First = "Michael Schumacher", Second = "David Coulthard", Third = "Rubens Barrichello" }); championships.Add(new Championship { Year = 2002, First = "Michael Schumacher", Second = "Rubens Barrichello", Third = "Juan Pablo Montoya" }); championships.Add(new Championship { Year = 2003, First = "Michael Schumacher", Second = "Kimi R?ikk?nen", Third = "Juan Pablo Montoya" }); championships.Add(new Championship { Year = 2004, First = "Michael Schumacher", Second = "Rubens Barrichello", Third = "Jenson Button" }); championships.Add(new Championship { Year = 2005, First = "Fernando Alonso", Second = "Kimi R?ikk?nen", Third = "Michael Schumacher" }); championships.Add(new Championship { Year = 2006, First = "Fernando Alonso", Second = "Michael Schumacher", Third = "Felipe Massa" }); championships.Add(new Championship { Year = 2007, First = "Kimi R?ikk?nen", Second = "Lewis Hamilton", Third = "Fernando Alonso" }); championships.Add(new Championship { Year = 2008, First = "Lewis Hamilton", Second = "Felipe Massa", Third = "Kimi Raikkonen" }); championships.Add(new Championship { Year = 2009, First = "Jenson Button", Second = "Sebastian Vettel", Third = "Rubens Barrichello" }); championships.Add(new Championship { Year = 2010, First = "Sebastian Vettel", Second = "Fernando Alonso", Third = "Mark Webber" }); championships.Add(new Championship { Year = 2011, First = "Sebastian Vettel", Second = "Jenson Button", Third = "Mark Webber" }); } return championships; } private static IList<Racer> moreRacers; private static IList<Racer> GetMoreRacers() { if (moreRacers == null) { moreRacers = new List<Racer>(); moreRacers.Add(new Racer("Luigi", "Fagioli", "Italy", starts: 7, wins: 1)); moreRacers.Add(new Racer("Jose Froilan", "Gonzalez", "Argentina", starts: 26, wins: 2)); moreRacers.Add(new Racer("Piero", "Taruffi", "Italy", starts: 18, wins: 1)); moreRacers.Add(new Racer("Stirling", "Moss", "UK", starts: 66, wins: 16)); moreRacers.Add(new Racer("Eugenio", "Castellotti", "Italy", starts: 14, wins: 0)); moreRacers.Add(new Racer("Peter", "Collins", "UK", starts: 32, wins: 3)); moreRacers.Add(new Racer("Luigi", "Musso", "Italy", starts: 24, wins: 1)); moreRacers.Add(new Racer("Tony", "Brooks", "UK", starts: 38, wins: 6)); moreRacers.Add(new Racer("Bruce", "McLaren", "New Zealand", starts: 100, wins: 4)); moreRacers.Add(new Racer("Wolfgang von", "Trips", "Germany", starts: 27, wins: 2)); moreRacers.Add(new Racer("Richie", "Ginther", "USA", starts: 52, wins: 1)); moreRacers.Add(new Racer("Jackie", "Ickx", "Belgium", starts: 116, wins: 8)); moreRacers.Add(new Racer("Clay", "Regazzoni", "Switzerland", starts: 132, wins: 5)); moreRacers.Add(new Racer("Ronnie", "Peterson", "Sweden", starts: 123, wins: 10)); moreRacers.Add(new Racer("Francois", "Cevert", "France", starts: 46, wins: 1)); moreRacers.Add(new Racer("Carlos", "Reutemann", "Argentina", starts: 146, wins: 12)); moreRacers.Add(new Racer("Gilles", "Villeneuve", "Canada", starts: 67, wins: 6)); moreRacers.Add(new Racer("Didier", "Pironi", "France", starts: 70, wins: 3)); moreRacers.Add(new Racer("John", "Watson", "UK", starts: 152, wins: 5)); moreRacers.Add(new Racer("Rene", "Arnoux", "France", starts: 149, wins: 7)); moreRacers.Add(new Racer("Elio", "de Angelis", "Italy", starts: 108, wins: 2)); moreRacers.Add(new Racer("Michele", "Alboreto", "Italy", starts: 194, wins: 5)); moreRacers.Add(new Racer("Gerhard", "Berger", "Austria", starts: 210, wins: 10)); moreRacers.Add(new Racer("Riccardo", "Patrese", "Italy", starts: 256, wins: 6)); moreRacers.Add(new Racer("David", "Coulthard", "UK", starts: 246, wins: 13)); moreRacers.Add(new Racer("Heinz-Harald", "Frentzen", "Germany", starts: 156, wins: 3)); moreRacers.Add(new Racer("Eddie", "Irvine", "UK", starts: 147, wins: 4)); moreRacers.Add(new Racer("Rubens", "Barrichello", "Brazil", starts: 322, wins: 11)); moreRacers.Add(new Racer("Juan Pablo", "Montoya", "Columbia", starts: 94, wins: 7)); moreRacers.Add(new Racer("Felipe", "Massa", "Brazil", starts: 152, wins: 11)); moreRacers.Add(new Racer("Mark", "Webber", "Australia", starts: 176, wins: 7)); } return moreRacers; } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Wrox.ProCSharp.LINQ { public class Championship { public int Year { get; set; } public string First { get; set; } public string Second { get; set; } public string Third { get; set; } } }
EnumerableSample
namespace Wrox.ProCSharp.LINQ { public class RacerInfo { public int Year { get; set; } public int Position { get; set; } public string FirstName { get; set; } public string LastName { get; set; } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Wrox.ProCSharp.LINQ { public static class StringExtension { public static string FirstName(this string name) { int ix = name.LastIndexOf(‘ ‘); return name.Substring(0, ix); } public static string LastName(this string name) { int ix = name.LastIndexOf(‘ ‘); return name.Substring(ix + 1); } } class Program { static void Main() { // Filtering(); // IndexFiltering(); // TypeFiltering(); // CompoundFrom(); // Sorting(); // Grouping(); // GroupingWithNestedObjects(); // InnerJoin(); // LeftOuterJoin(); // GroupJoin2(); // SetOperations(); // Except(); // ZipOperation(); // Partitioning(); // Aggregate(); // Aggregate2(); Untyped(); // CombineRacers(); // SelectMany2(); Console.ReadKey(); } private static void SelectMany2() { // flatten the year list to return a list of all racers and positions in the championship var racers = Formula1.GetChampionships() .SelectMany(cs => new List<dynamic>() { new { Year = cs.Year, Position = 1, Name = cs.First }, new { Year = cs.Year, Position = 2, Name = cs.Second }, new { Year = cs.Year, Position = 3, Name = cs.Third } }); foreach (var s in racers) { Console.WriteLine(s); } } private static void CombineRacers() { var q = from r in Formula1.GetChampions() join r2 in Formula1.GetChampionships().GetRacerInfo() on new { FirstName = r.FirstName, LastName = r.LastName } equals new { FirstName = r2.FirstName, LastName = r2.LastName } into yearResults select new { FirstName = r.FirstName, LastName = r.LastName, Wins = r.Wins, Starts = r.Starts, Results = yearResults }; foreach (var item in q) { Console.WriteLine("{0} {1}", item.FirstName, item.LastName); foreach (var item2 in item.Results) { Console.WriteLine("{0} {1}", item2.Year, item2.Position); } } } private static void Except() { var racers = Formula1.GetChampionships().SelectMany(cs => new List<RacerInfo>() { new RacerInfo { Year = cs.Year, Position = 1, FirstName = cs.First.FirstName(), LastName = cs.First.LastName() }, new RacerInfo { Year = cs.Year, Position = 2, FirstName = cs.Second.FirstName(), LastName = cs.Second.LastName() }, new RacerInfo { Year = cs.Year, Position = 3, FirstName = cs.Third.FirstName(), LastName = cs.Third.LastName() } }); var nonChampions = racers.Select(r => new { FirstName = r.FirstName, LastName = r.LastName }).Except(Formula1.GetChampions().Select(r => new { FirstName = r.FirstName, LastName = r.LastName })); foreach (var r in nonChampions) { Console.WriteLine("{0} {1}", r.FirstName, r.LastName); } } private static void Sorting() { var racers = (from r in Formula1.GetChampions() orderby r.Country, r.LastName, r.FirstName select r).Take(10); foreach (var racer in racers) { Console.WriteLine("{0}: {1}, {2}", racer.Country, racer.LastName, racer.FirstName); } } static void Untyped() { var list = new System.Collections.ArrayList(Formula1.GetChampions() as System.Collections.ICollection); var query = from r in list.Cast<Racer>() where r.Country == "USA" orderby r.Wins descending select r; foreach (var racer in query) { Console.WriteLine("{0:A}", racer); } } static void ZipOperation() { var racerNames = from r in Formula1.GetChampions() where r.Country == "Italy" orderby r.Wins descending select new { Name = r.FirstName + " " + r.LastName }; var racerNamesAndStarts = from r in Formula1.GetChampions() where r.Country == "Italy" orderby r.Wins descending select new { LastName = r.LastName, Starts = r.Starts }; var racers = racerNames.Zip(racerNamesAndStarts, (first, second) => first.Name + ", starts: " + second.Starts); foreach (var r in racers) { Console.WriteLine(r); } } static void Aggregate2() { var countries = (from c in from r in Formula1.GetChampions() group r by r.Country into c select new { Country = c.Key, Wins = (from r1 in c select r1.Wins).Sum() } orderby c.Wins descending, c.Country select c).Take(5); foreach (var country in countries) { Console.WriteLine("{0} {1}", country.Country, country.Wins); } } static void Aggregate() { var query = from r in Formula1.GetChampions() let numberYears = r.Years.Count() where numberYears >= 3 orderby numberYears descending, r.LastName select new { Name = r.FirstName + " " + r.LastName, TimesChampion = numberYears }; foreach (var r in query) { Console.WriteLine("{0} {1}", r.Name, r.TimesChampion); } } static void Partitioning() { int pageSize = 5; int numberPages = (int)Math.Ceiling(Formula1.GetChampions().Count() / (double)pageSize); for (int page = 0; page < numberPages; page++) { Console.WriteLine("Page {0}", page); var racers = (from r in Formula1.GetChampions() orderby r.LastName, r.FirstName select r.FirstName + " " + r.LastName). Skip(page * pageSize).Take(pageSize); foreach (var name in racers) { Console.WriteLine(name); } Console.WriteLine(); } } static void SetOperations() { Func<string, IEnumerable<Racer>> racersByCar = car => from r in Formula1.GetChampions() from c in r.Cars where c == car orderby r.LastName select r; Console.WriteLine("World champion with Ferrari and McLaren"); foreach (var racer in racersByCar("Ferrari").Intersect(racersByCar("McLaren"))) { Console.WriteLine(racer); } } static void InnerJoin() { var racers = from r in Formula1.GetChampions() from y in r.Years select new { Year = y, Name = r.FirstName + " " + r.LastName }; var teams = from t in Formula1.GetContructorChampions() from y in t.Years select new { Year = y, Name = t.Name }; var racersAndTeams = (from r in racers join t in teams on r.Year equals t.Year orderby t.Year select new { Year = r.Year, Champion = r.Name, Constructor = t.Name }).Take(10); Console.WriteLine("Year World Champion\t Constructor Title"); foreach (var item in racersAndTeams) { Console.WriteLine("{0}: {1,-20} {2}", item.Year, item.Champion, item.Constructor); } Console.WriteLine(); racers = Formula1.GetChampions().SelectMany(r => r.Years, (r, y) => new { Year = y, Name = r.FirstName + " " + r.LastName }); teams = Formula1.GetContructorChampions().SelectMany(t => t.Years, (t, y) => new { Year = y, Name = t.Name }); racersAndTeams = racers.Join(teams, r => r.Year, t => t.Year, (r, t) => new { Year = r.Year, Champion = r.Name, Constructor = t.Name }).OrderBy(_=>_.Year).Take(10); Console.WriteLine("Year World Champion\t Constructor Title"); foreach (var item in racersAndTeams) { Console.WriteLine("{0}: {1,-20} {2}", item.Year, item.Champion, item.Constructor); } } static void GroupJoin2() { var racers = Formula1.GetChampionships() .SelectMany(cs => new List<RacerInfo>() { new RacerInfo { Year = cs.Year, Position = 1, FirstName = cs.First.FirstName(), LastName = cs.First.LastName() }, new RacerInfo { Year = cs.Year, Position = 2, FirstName = cs.Second.FirstName(), LastName = cs.Second.LastName() }, new RacerInfo { Year = cs.Year, Position = 3, FirstName = cs.Third.FirstName(), LastName = cs.Third.LastName() } }); var q = (from r in Formula1.GetChampions() join r2 in racers on new { FirstName = r.FirstName, LastName = r.LastName } equals new { FirstName = r2.FirstName, LastName = r2.LastName } into yearResults select new { FirstName = r.FirstName, LastName = r.LastName, Wins = r.Wins, Starts = r.Starts, Results = yearResults }); foreach (var r in q) { Console.WriteLine("{0} {1}", r.FirstName, r.LastName); foreach (var results in r.Results) { Console.WriteLine("{0} {1}", results.Year, results.Position); } } } static void GroupJoin() { // var q = //from c in categories //join p in products on c equals p.Category into ps //select new { Category = c, Products = ps }; var racers = from r in Formula1.GetChampions() from y in r.Years select new { Year = y, Name = r.FirstName + " " + r.LastName }; var teams = from t in Formula1.GetContructorChampions() from y in t.Years select new { Year = y, Name = t.Name }; var racersAndTeams = from r in racers join t in teams on r.Year equals t.Year into ts select new { Year = r.Year, Racer = r.Name, Constructor = ts }; foreach (var r in racersAndTeams) { Console.WriteLine("{0} {1}", r.Year, r.Racer); foreach (var t in r.Constructor) { Console.WriteLine("\t{0}", t.Name); } } } static void CrossJoinWithGroupJoin() { // var q = //from c in categories //join p in products on c equals p.Category into ps //from p in ps //select new { Category = c, p.ProductName }; } static void LeftOuterJoin() { var racers = from r in Formula1.GetChampions() from y in r.Years select new { Year = y, Name = r.FirstName + " " + r.LastName }; var teams = from t in Formula1.GetContructorChampions() from y in t.Years select new { Year = y, Name = t.Name }; var racersAndTeams = (from r in racers join t in teams on r.Year equals t.Year into rt from t in rt.DefaultIfEmpty() orderby r.Year select new { Year = r.Year, Champion = r.Name, Constructor = t == null ? "no constructor championship" : t.Name }).Take(10); Console.WriteLine("Year Champion\t\t Constructor Title"); foreach (var item in racersAndTeams) { Console.WriteLine("{0}: {1,-20} {2}", item.Year, item.Champion, item.Constructor); } } static void GroupingWithNestedObjects() { var countries = from r in Formula1.GetChampions() group r by r.Country into g orderby g.Count() descending, g.Key where g.Count() >= 2 select new { Country = g.Key, Count = g.Count(), Racers = from r1 in g orderby r1.LastName select r1.FirstName + " " + r1.LastName }; foreach (var item in countries) { Console.WriteLine("{0, -10} {1}", item.Country, item.Count); foreach (var name in item.Racers) { Console.Write("{0}; ", name); } Console.WriteLine(); } Console.WriteLine(); Console.WriteLine(); var countries1 = Formula1.GetChampions().GroupBy(_ => _.Country).OrderByDescending(_ => _.Count()).ThenBy(_ => _.Key).Where(_ => _.Count() >= 2).Select(_ => new { Country = _.Key, Count = _.Count(), Racers = _.OrderBy(r => r.LastName).Select(r => r.FirstName + " " + r.LastName) }); foreach (var item in countries1) { Console.WriteLine("{0, -10} {1}", item.Country, item.Count); foreach (var name in item.Racers) { Console.Write("{0}; ", name); } Console.WriteLine(); } } static void Grouping() { var countries = from r in Formula1.GetChampions() group r by r.Country into g orderby g.Count() descending, g.Key where g.Count() >= 2 select new { Country = g.Key, Count = g.Count() }; foreach (var item in countries) { Console.WriteLine("{0, -10} {1}", item.Country, item.Count); } } static void CompoundFrom() { 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(racer); } } static void TypeFiltering() { object[] data = http://www.mamicode.com/{ "one", 2, 3, "four", "five", 6 }; var query = data.OfType<string>(); foreach (var s in query) { Console.WriteLine(s); } } static void IndexFiltering() { var racers = Formula1.GetChampions(). Where((r, index) => r.LastName.StartsWith("A") && index % 2 != 0); foreach (var r in racers) { Console.WriteLine("{0:A}", r); } } static void Filtering() { var racers = from r in Formula1.GetChampions() where r.Wins > 15 && (r.Country == "Brazil" || r.Country == "Austria") select r; foreach (var r in racers) { Console.WriteLine("{0:A}", r); } } } }
using System; using System.Collections.Generic; namespace Wrox.ProCSharp.LINQ { public static class ChampionshipExtension { public static IEnumerable<RacerInfo> GetRacerInfo(this IEnumerable<Championship> source) { Func<string, string[]> split = s => { string[] result = new string[2]; int ix = s.LastIndexOf(‘ ‘); result[0] = s.Substring(0, ix); result[1] = s.Substring(ix + 1); return result; }; Func<int, int, string[], RacerInfo> getRacerInfo = (year, place, names) => new RacerInfo { Year = year, Position = place, FirstName = names[0], LastName = names[1] }; foreach (var item in source) { yield return getRacerInfo(item.Year, 1, split(item.First)); yield return getRacerInfo(item.Year, 2, split(item.Second)); yield return getRacerInfo(item.Year, 3, split(item.Third)); } } } }
ExpressionTreeSample
using System; using System.Linq.Expressions; namespace Wrox.ProCSharp.LINQ { class Program { private static void DisplayTree(int indent, string message, Expression expression) { string output = String.Format("{0} {1} ! NodeType: {2}; Expr: {3} ", "".PadLeft(indent, ‘>‘), message, expression.NodeType, expression); indent++; switch (expression.NodeType) { case ExpressionType.Lambda: Console.WriteLine(output); LambdaExpression lambdaExpr = (LambdaExpression)expression; foreach (var parameter in lambdaExpr.Parameters) { DisplayTree(indent, "Parameter", parameter); } DisplayTree(indent, "Body", lambdaExpr.Body); break; case ExpressionType.Constant: ConstantExpression constExpr = (ConstantExpression)expression; Console.WriteLine("{0} Const Value: {1}", output, constExpr.Value); break; case ExpressionType.Parameter: ParameterExpression paramExpr = (ParameterExpression)expression; Console.WriteLine("{0} Param Type: {1}", output, paramExpr.Type.Name); break; case ExpressionType.Equal: case ExpressionType.AndAlso: case ExpressionType.GreaterThan: BinaryExpression binExpr = (BinaryExpression)expression; if (binExpr.Method != null) { Console.WriteLine("{0} Method: {1}", output, binExpr.Method.Name); } else { Console.WriteLine(output); } DisplayTree(indent, "Left", binExpr.Left); DisplayTree(indent, "Right", binExpr.Right); break; case ExpressionType.MemberAccess: MemberExpression memberExpr = (MemberExpression)expression; Console.WriteLine("{0} Member Name: {1}, Type: {2}", output, memberExpr.Member.Name, memberExpr.Type.Name); DisplayTree(indent, "Member Expr", memberExpr.Expression); break; default: Console.WriteLine(); Console.WriteLine("{0} {1}", expression.NodeType, expression.Type.Name); break; } } static void Main() { Expression<Func<Racer, bool>> expression = r => r.Country == "Brazil" && r.Wins > 6; DisplayTree(0, "Lambda", expression); } } }
LINQIntro
using System; using System.Collections.Generic; using System.Linq; namespace Wrox.ProCSharp.LINQ { class Program { static void Main() { LINQQuery(); //ExtensionMethods(); //DeferredQuery(); Console.ReadKey(); } static void DeferredQuery() { var names = new List<string> { "Nino", "Alberto", "Juan", "Mike", "Phil" }; var namesWithJ = from n in names where n.StartsWith("J") orderby n select n; Console.WriteLine("First iteration"); foreach (string name in namesWithJ) { Console.WriteLine(name); } Console.WriteLine(); names.Add("John"); names.Add("Jim"); names.Add("Jack"); names.Add("Denny"); Console.WriteLine("Second iteration"); foreach (string name in namesWithJ) { Console.WriteLine(name); } } static void ExtensionMethods() { var champions = new List<Racer>(Formula1.GetChampions()); IEnumerable<Racer> brazilChampions = champions.Where(r => r.Country == "Brazil"). OrderByDescending(r => r.Wins). Select(r => r); foreach (Racer r in brazilChampions) { Console.WriteLine("{0:A}", r); } } static void LINQQuery() { var query = from r in Formula1.GetChampions() where r.Country == "Brazil" orderby r.Wins descending select r; foreach (var r in query) { Console.WriteLine("{0:A}", r); } } } }
ParallelLinqSample
using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace Wrox.ProCSharp.Linq { class Program { static void Main() { IntroParallel(); // Cancellation(); } static void Cancellation() { var data =http://www.mamicode.com/ SampleData(); Console.WriteLine("filled array"); var sum1 = (from x in data where Math.Log(x) < 4 select x).Average(); Console.WriteLine("sync result {0}", sum1); var cts = new CancellationTokenSource(); Task.Factory.StartNew(() => { try { var res = (from x in data.AsParallel().WithCancellation(cts.Token) where Math.Log(x) < 4 select x).Average(); Console.WriteLine("query finished, result: {0}", res); } catch (OperationCanceledException ex) { Console.WriteLine(ex.Message); } }); Console.WriteLine("query started"); Console.Write("cancel? "); string input = Console.ReadLine(); if (input.ToLower().Equals("y")) { cts.Cancel(); Console.WriteLine("sent a cancel"); } Console.WriteLine("press return to exit"); Console.ReadLine(); } static IEnumerable<int> SampleData() { const int arraySize = 100000000; var r = new Random(); return Enumerable.Range(0, arraySize).Select(x => r.Next(140)).ToList(); } static void IntroParallel() { var data =http://www.mamicode.com/ SampleData(); var watch = new Stopwatch(); watch.Start(); var q1 = (from x in data where Math.Log(x) < 4 select x).Average(); watch.Stop(); Console.WriteLine("sync {0}, result: {1}", watch.ElapsedMilliseconds, q1); watch.Reset(); watch.Start(); var q2 = (from x in Partitioner.Create(data).AsParallel() where Math.Log(x) < 4 select x).Average(); watch.Stop(); Console.WriteLine("async {0}, result: {1}", watch.ElapsedMilliseconds, q2); } } }
第十一章 LINQ
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。