首页 > 代码库 > 第十一章 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; }
    }
}
View Code
技术分享
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));
      }
    }
  }
}
View Code
技术分享
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;
    }
  }
}
View Code
技术分享
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; }
  }
}
View Code

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; }
  }
}
View Code
技术分享
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);
      }

    }
  }
}
View Code
技术分享
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));
      }
    }
  }


}
View Code

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);

        }
    }
}
View Code

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);
      }

    }
  }
}
View Code

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);
    }
  }
}
View Code

 

第十一章 LINQ