Esempio n. 1
0
        /// <summary>
        /// 对嵌套的对象分组
        /// </summary>
        public void Fun4()
        {
            var query = 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 query)
            {
                Console.WriteLine($"{item.Country,-10}{item.Count}");
                foreach (var i in item.Racers)
                {
                    Console.Write($"{i},");
                }
                Console.WriteLine();
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Where筛选条件
        /// </summary>
        public void Fun3()
        {
            //并不是所有的查询都可以用Linq查询语法完成。也不是所有的拓展方法都映射到Linq查询子句上。高级查询需要使用拓展方法。
            var racers = Formula1.GetChampions().Where((r, index) =>
            {
                return(r.Wins > 15 && (r.Country == "USA" || r.Country == "UK"));
            }).Select(r => r);

            Console.WriteLine("使用拓展方法");
            foreach (var item in racers)
            {
                Console.WriteLine(item.ToString("A"));
            }
            Console.WriteLine("------------------------");
            var query = from r in Formula1.GetChampions()
                        where r.Wins > 15 && (r.Country == "USA" || r.Country == "UK")
                        select r;

            Console.WriteLine("使用Linq查询");
            foreach (var item in query)
            {
                Console.WriteLine(item.ToString("A"));
            }
            Console.Read();
        }
Esempio n. 3
0
        static void DeconstructWithExtensionsMethods()
        {
            var racer = Formula1.GetChampions().Where(r => r.LastName == "Lauda").First();

            (string first, string last, _, _) = racer;
            Console.WriteLine($"{first} {last}");
        }
        //分组
        public static void Grouping()
        {
            //g.group r by r.Country和.GroupBy(r => r.Country)的Country关键字
            var countries = from r in Formula1.GetChampions()
                            group r by r.Country into g
                            let count = g.Count()   //可以在查询中使用let创建变量以便在以后的查询中使用
                                        orderby count descending, g.Key
            where count >= 2
            select new
            {
                Country = g.Key,
                Count   = count
            };

            countries = Formula1.GetChampions()
                        .GroupBy(r => r.Country)
                        .Select(g => new { Group = g, Count = g.Count() }) //这里可以用Select创建一个临时匿名类型
                        .OrderByDescending(g => g.Count)                   //这里就可以使用上面临时匿名类型的属性而不是方法了
                        .ThenBy(g => g.Group.Key)                          //但是这里要调用Key的话就需要调用Group属性的Key
                        .Where(g => g.Count >= 2)
                        .Select(g => new
            {
                Country = g.Group.Key,
                Count   = g.Count
            });


            foreach (var item in countries)
            {
                Console.WriteLine($"Country: {item.Country, -10} Count: {item.Count}");
            }
        }
Esempio n. 5
0
        /// <summary>
        /// 复合的from子句
        /// </summary>
        public void Fun5()
        {
            Console.WriteLine("----------Linq查询----------");
            var query = from r in Formula1.GetChampions()
                        from c in r.Cars
                        where c == "Ferrari"
                        orderby r.LastName
                        select r.FirstName + " " + r.LastName;

            foreach (var item in query)
            {
                Console.WriteLine(item);
            }

            Console.WriteLine("----------拓展方法----------");
            //SelectMany将Racer和Cars合并起来!
            var query2 = 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);

            foreach (var item in query2)
            {
                Console.WriteLine(item);
            }

            Console.WriteLine("----------SelectMany()----------");
            var query3 = Formula1.GetChampions().SelectMany(r => r.Cars).Select(r => r);

            foreach (var item in query3)
            {
                Console.WriteLine(item);
            }
            Console.Read();
        }
    public static void Except()
    {
        Console.WriteLine("Show the list of Formula 1 drives that have been in the top 3 but never a world champion");

        var racers = Formula1.GetChampionships().SelectMany(cs => new List <RacerInfo>()
        {
            new RacerInfo(cs.Year, 1, cs.First.FirstName(), cs.First.LastName()),
            new RacerInfo(cs.Year, 2, cs.Second.FirstName(), cs.Second.LastName()),
            new RacerInfo(cs.Year, 3, cs.Third.FirstName(), cs.Third.LastName())
        });

        var nonChampions = racers.Select(r =>
                                         new
        {
            r.FirstName,
            r.LastName
        }).Except(Formula1.GetChampions().Select(r =>
                                                 new
        {
            r.FirstName,
            r.LastName
        }));

        foreach (var r in nonChampions)
        {
            Console.WriteLine($"{r.FirstName} {r.LastName}");
        }
    }
Esempio n. 7
0
        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);
            //}
        }
Esempio n. 8
0
        // 12.2.14 分区
        public 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 {page}");

                /*
                 * 把扩展方法Skip()和Take()添加到查询的最后。
                 * Skip()方法先忽略根据页面大小和实际页数计算出的项数,
                 * 在使用Take()方法根据页面大小提取一定数量的项。
                 *
                 * 使用TakeWhile()和SkipWhile()扩展方法,还可以传递一个谓词,
                 * 根据结果提取或跳过某些项。
                 */
                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();
            }
        }
Esempio n. 9
0
        // 12.2.13 合并
        public 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
            {
                r.LastName,
                r.Starts
            };

            /*
             * Zip()对于合并,第一个集合中的第一项和第二个集合中的第一项合并,
             * 第一个集合中第二项会与第二个集合中的第二项合并,以此内推。
             * 如果两个序列的项数不同,就在到达较小集合的末尾时停止。
             *
             * 通过参数first接收第一个集合的元素,通过参数second接收第二个集合的元素。
             */
            var racers = racerNames.Zip(racerNamesAndStarts, (first, second) => first.Name + ", starts: " + second.Starts);

            foreach (var r in racers)
            {
                Console.WriteLine(r);
            }
        }
        public static void CompoundFromWithMethods()
        {
            /*
             * 第一个参数是隐式参数,它从GetChampions()方法中接受Racer对象序列;
             *
             * 第二个参数是collectionSelector委托,其中定义了内部序列。
             * 在lambda表达式r =>r.Cars中,应返回赛车集合;
             *
             * 第三个参数是一个委托,现在为每个赛车调用该委托,接收Racer和Car对象。
             * lambda表达式创建了一个匿名类型,它有Racer和Car属性。
             *
             * 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);

            //.SelectMany(r => r.Cars, (r1, cars) => new { Racer1 = r1, Cars1 = cars })
            //.Where(item => item.Cars1.Contains("Ferrari"))
            //.OrderBy(item => item.Racer1.LastName)
            //.Select(item => $"{item.Racer1.FirstName} {item.Racer1.LastName}");

            foreach (var racer in ferrariDrivers)
            {
                Console.WriteLine(racer);
            }
        }
Esempio n. 11
0
        public static void AggregateSum()
        {
            /*
             * Sum()方法汇总序列中的所有数字,返回这些数字的和。
             *
             * 首先根据国家对赛车手分组,再在新创建的匿名类型中,
             * 把Wins属性赋予某个国家赢得比赛的总次数。
             */
            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($"{country.Country} {country.Wins}");
            }
        }
Esempio n. 12
0
        /// <summary>
        /// 对嵌套的对象分组
        /// </summary>
        public void Fun3()
        {
            var query = from r in Formula1.GetChampions()
                        group r by r.Country into g
                        let count = g.Count()
                                    orderby count descending, g.Key
            where count >= 2
            select new
            {
                Country = g.Key,
                Count   = count,
                Racers  = from r1 in g
                          orderby r1.LastName
                          select r1.FirstName + " " + r1.LastName
            };

            foreach (var item in query)
            {
                Console.WriteLine($"{item.Country,-10} {item.Count}");
                foreach (var name in item.Racers)
                {
                    Console.Write(name + ",");
                }
                Console.WriteLine();
            }
            Console.Read();
        }
Esempio n. 13
0
        /// <summary>
        /// 内连接
        /// </summary>
        public void Fun4()
        {
            var racers = from r in Formula1.GetChampions()
                         from y in r.Years
                         select new
            {
                Year = y,
                Name = r.FirstName + " " + r.LastName
            };

            var teams = from r in Formula1.GetConstructorChampions()
                        from y in r.Years
                        select new
            {
                Year = y,
                Name = r.Name
            };

            var query = from r in racers
                        join t in teams on r.Year equals t.Year
                        select new
            {
                Year  = r.Year,
                Racer = r.Name,
                Team  = t.Name
            };

            foreach (var item in query)
            {
                Console.WriteLine(item.Racer + "--" + item.Team + "--" + item.Year);
            }
            Console.Read();
        }
Esempio n. 14
0
        /// <summary>
        /// 集合操作
        /// </summary>
        public void Fun7()
        {
            //下面创造一个驾驶法拉第的一级方程式冠军和驾驶迈凯伦的一级方程式冠军,然后确定是否有驾驶法拉第和迈凯伦的冠军
            //var q = from r in Formula1.GetChampions()
            //        from c in r.Cars
            //        where c == "Ferrari"
            //        orderby r.LastName
            //        select r;

            //var q2 = from r in Formula1.GetChampions()
            //        from c in r.Cars
            //        where c == "McLaren"
            //        orderby r.LastName
            //        select r;

            //等价于

            Func <string, IEnumerable <Racer> > racersByCar =
                car => from r in Formula1.GetChampions()
                from c in r.Cars
                where c == car
                orderby r.LastName
                select r;

            foreach (var item in racersByCar("Ferrari").Intersect(racersByCar("McLaren")))
            {
                Console.WriteLine($"{item.FirstName} {item.LastName}");
            }
        }
Esempio n. 15
0
        static void GroupJoinWithMethods()
        {
            var racers = Formula1.GetChampionships()
                         .SelectMany(cs => new List <(int Year, int Position, string FirstName, string LastName)>
            {
                (cs.Year, Position: 1, FirstName: cs.First.FirstName(), LastName: cs.First.LastName()),
                (cs.Year, Position: 2, FirstName: cs.Second.FirstName(), LastName: cs.Second.LastName()),
                (cs.Year, Position: 3, FirstName: cs.Third.FirstName(), LastName: cs.Third.LastName())
            });

            var q = Formula1.GetChampions()
                    .GroupJoin(racers,
                               r1 => (r1.FirstName, r1.LastName),
                               r2 => (r2.FirstName, r2.LastName),
                               (r1, r2s) => (r1.FirstName, r1.LastName, r1.Wins, r1.Starts, Results: r2s));


            foreach (var r in q)
            {
                Console.WriteLine($"{r.FirstName} {r.LastName}");
                foreach (var results in r.Results)
                {
                    Console.WriteLine($"{results.Year} {results.Position}");
                }
            }
        }
        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()
            };

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

            foreach (var item in countries)
            {
                Console.WriteLine($"{item.Country,-10} {item.Count}");
            }
        }
    public static void Partitioning()
    {
        Console.WriteLine("split returned data from a query with Skip and Take methods");

        int pageSize = 5;

        int numberPages = (int)Math.Ceiling(Formula1.GetChampions().Count() /
                                            (double)pageSize);

        for (int page = 0; page < numberPages; page++)
        {
            Console.WriteLine($"Page {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();
        }
    }
        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($"{racer.Country}: {racer.LastName}, {racer.FirstName}");
            }

            Console.WriteLine();

            // use method syntax
            var racers2 = Formula1.GetChampions()
                          .OrderBy(r => r.Country)
                          .ThenBy(r => r.LastName)
                          .ThenBy(r => r.FirstName)
                          .Take(10);

            foreach (var racer in racers2)
            {
                Console.WriteLine($"{racer.Country}: {racer.LastName}, {racer.FirstName}");
            }
        }
    public static void Zip()
    {
        Console.WriteLine("Use Zip to combine collections - names of Italian champions and a second list with number of starts from Italian champions");

        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
        {
            r.LastName,
            r.Starts
        };

        var racers = racerNames.Zip(racerNamesAndStarts, (first, second) => first.Name + ", starts: " + second.Starts);

        foreach (var r in racers)
        {
            Console.WriteLine(r);
        }
    }
Esempio n. 20
0
        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.GetConstructorChampions()
                        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($"{item.Year}: {item.Champion,-20} {item.Constructor}");
            }
        }
Esempio n. 21
0
    public static void GroupingAndNestedObjectsWithMethods()
    {
        Console.WriteLine("Using method syntax to return nested objects");

        var countries = Formula1.GetChampions()
                        .GroupBy(r => r.Country)
                        .Select(g => new
        {
            Group = g,
            g.Key,
            Count = g.Count()
        })
                        .OrderByDescending(g => g.Count)
                        .ThenBy(g => g.Key)
                        .Where(g => g.Count >= 2)
                        .Select(g => new
        {
            Country = g.Key,
            g.Count,
            Racers = g.Group.OrderBy(r => r.LastName).Select(r => r.FirstName + " " + r.LastName)
        });

        foreach (var item in countries)
        {
            Console.WriteLine($"{item.Country,-10} {item.Count}");
            foreach (var name in item.Racers)
            {
                Console.Write($"{name}; ");
            }
            Console.WriteLine();
        }
    }
Esempio n. 22
0
    public static void GroupingAndNestedObjects()
    {
        Console.WriteLine("returning nested objects with a LINQ query");

        var countries = from r in Formula1.GetChampions()
                        group r by r.Country into g
                        let count = g.Count()
                                    orderby count descending, g.Key
        where count >= 2
        select new
        {
            Country = g.Key,
            Count   = count,
            Racers  = from r1 in g
                      orderby r1.LastName
                      select r1.FirstName + " " + r1.LastName
        };

        foreach (var item in countries)
        {
            Console.WriteLine($"{item.Country,-10} {item.Count}");
            foreach (var name in item.Racers)
            {
                Console.Write($"{name}; ");
            }
            Console.WriteLine();
        }
    }
Esempio n. 23
0
        private static void CombineRacers()
        {
            var q = from r in Formula1.GetChampions()
                    join r2 in Formula1.GetChampionships().GetRacerInfo() on
                    (
                FirstName: r.FirstName,
                LastName: r.LastName
                    )
                    equals
                    (
                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)
            {
                WriteLine($"{item.FirstName} {item.LastName}");
                foreach (var item2 in item.Results)
                {
                    WriteLine($"{item2.Year} {item2.Position}");
                }
            }
        }
Esempio n. 24
0
        static void GruopingWithVariables()
        {
            var countries = from r in Formula1.GetChampions()
                            group r by r.Country into g
                            let count = g.Count()
                                        orderby count descending, g.Key
            where count >= 2
            select new
            {
                Country = g.Key,
                Count   = count
            };

            foreach (var i in countries)
            {
                Console.WriteLine($"{ i.Country,-50} {i.Count}");
            }

            var Countries1 = Formula1.GetChampions()
                             .GroupBy(r => r.Country)
                             .Select(g => new { Group = g, Count = g.Count() })
                             .OrderByDescending(q => q.Count)
                             .ThenBy(g => g.Group.Key)
                             .Where(g => g.Count >= 2)
                             .Select(g => new
            {
                Country = g.Group.Key,
                Count   = g.Count
            });

            foreach (var i in Countries1)
            {
                Console.WriteLine($"{ i.Country,-50} {i.Count}");
            }
        }
        // 分组
        public static void Grouping()
        {
            /*
             * 子句group r by r.Country into g根据Country属性组合所有的赛车手
             * 并定义一个新的标识符g,它以后用于访问分组的结果信息。
             *
             * group子句的结果根据应用到的分组结果上的扩展方法Count()来排序,
             * 如果冠军数相同,就根据关键字来排序,该关键字分组所用的关键字国家。
             *
             * where子句根据至少有两项的分组来筛选结果,
             * select子句创建一个带Country和Count属性的匿名类型
             */

            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($"{item.Country,-10} {item.Count}");
            }
        }
Esempio n. 26
0
        static void GroupBy()
        {
            var Countries1 = 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 i in Countries1)
            {
                Console.WriteLine($"{ i.Country,-50} {i.Count}");
            }


            var Countries = Formula1.GetChampions()
                            .GroupBy(r => r.Country)
                            .OrderByDescending(q => q.Count())
                            .ThenBy(q => q.Key)
                            .Where(r => r.Count() > 2)
                            .Select(q => new
            {
                Country = q.Key,
                Count   = q.Count()
            });

            foreach (var i in Countries)
            {
                Console.WriteLine($"{ i.Country,-50} {i.Count}");
            }
        }
Esempio n. 27
0
        static void SelectMany()
        {
            var ferrariDrivers = from r in Formula1.GetChampions()
                                 from c in r.Cars
                                 where c == "Ferrari"
                                 orderby r.LastName
                                 select r;

            foreach (var i in ferrariDrivers)
            {
                Console.WriteLine(i.FirstName + " " + i.LastName);
            }

            Console.WriteLine(" ");

            var ferrariDrivers1 = 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);

            foreach (var i in ferrariDrivers1)
            {
                Console.WriteLine(i.Racer.FirstName + i.Racer.LastName);
            }
        }
Esempio n. 28
0
        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);
                }
            }
        }
Esempio n. 29
0
        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();
            }
        }
Esempio n. 30
0
        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);
                }
            }
        }