码迷,mamicode.com
首页 > Windows程序 > 详细

《C#高级编程》读书笔记(八):LINQ

时间:2016-07-10 23:02:44      阅读:255      评论:0      收藏:0      [点我收藏+]

标签:

1,LINQ查询

            var query = from r in Formula1.GetChampion()
                where r.Country == "Brazil"
                orderby r.Wins descending 
                select r;
            foreach (var racer in query)
            {
                Console.WriteLine($"{racer:A}");
            }

    语法:查询表达式必须以from子句开头,以select活group子句结束。在这两个子句之间,可以使用where、orderby、join、let和其他from子句。

    执行:如上,变量query只指定了LINQ查询。该查询不是通过这个赋值语句执行的,只要使用foreach循环访问查询,该查询就会执行。

            var names = new List<string> {"Nino", "Alberto", "Juan"};
            var namesWithJ = from n in names
                where n.StartsWith("J")
                orderby n
                select n;
            Console.WriteLine("First iteration:");
            foreach (var n in namesWithJ)
            {
                Console.WriteLine(n);
            }

            names.AddRange(new []{
                "John",
                "Jim",
                "Jason"
            });
            Console.WriteLine("Second iteration:");
            foreach (var n in namesWithJ)
            {
                Console.WriteLine(n);
            }

输出:    

First iteration:
Juan
Second iteration:
Jason
Jim
John
Juan

    但是如果用了ToArray()、ToList(),查询结果将保持不变。

            var names = new List<string> {"Nino", "Alberto", "Juan"};
            var namesWithJ = (from n in names
                where n.StartsWith("J")
                orderby n
                select n).ToList();
            Console.WriteLine("First iteration:");
            foreach (var n in namesWithJ)
            {
                Console.WriteLine(n);
            }

            names.AddRange(new []{
                "John",
                "Jim",
                "Jason"
            });
            Console.WriteLine("Second iteration:");
            foreach (var n in namesWithJ)
            {
                Console.WriteLine(n);
            }

输出:

First iteration:
Juan
Second iteration:
Juan

2,复合的from语句

            var farrariDrivers = from r in Formula1.GetChampion()
                from c in r.Cars
                where c == "Ferrari"
                orderby r.LastName
                select r.FirstName + " " + r.LastName;
            foreach (var r in farrariDrivers)
            {
                Console.WriteLine(r);
            }

3,Take扩展方法

    获取查询结果前10条

var racers = (from r in Formula1.GetChampion()
                orderby r.Country, r.LastName, r.FirstName
                select r).Take(10);

4,分组

            var countries = from r in Formula1.GetChampion()
                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}");
            }

5,内连接

            var racers = from r in Formula1.GetChampion()
                from y in r.Years
                select new
                {
                    Year =y,
                    Name = r.ToString()
                };
            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
                select new
                {
                    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}");
            }

输出:

Year World Champion Constructor Title
1958:Mike Hawthorn Vanwall
1961:Phil Hill Ferrari
1964:John Surtees Ferrari
1963:Jim Clark Lotus
1965:Jim Clark Lotus
1959:Jack Brabham Cooper
1960:Jack Brabham Cooper
1966:Jack Brabham Brabham
1967:Denny Hulme Brabham
1962:Graham Hill BRM

6,左外链接

            var racersAndTeams = (from r in racers
                join t in teams on r.Year equals t.Year into rt
                from t in rt.DefaultIfEmpty()
                select new
                {
                    r.Year,
                    Champion = r.Name,
                    Constructor = t == null ?"no constructor championship":t.Name
                }
                ).Take(10);

    红色的部分是和内连接不一样的地方

    左外连接返回左边序列中的全部元素,即使他们在右边的序列中并没有匹配的元素。

7,集合操作

            //定义一个委托保存LINQ查询
            Func<string,IEnumerable<Racer>> racersByCar =
                car => from r in Formula1.GetChampion()
                    from c in r.Cars
                    where c == car
                    orderby r.LastName
                    select r;
            //用Intersect()扩展方法,获得驾驶法拉利和迈凯伦的所有冠军
            Console.WriteLine("World champion with Ferrari and Mclaren:");
            foreach (var racer in racersByCar("Ferrari").Intersect(racersByCar("McLaren")))
            {
                Console.WriteLine(racer);
            }

输出:

World champion with Ferrari and Mclaren:
Niki Lauda

8,合并

            var racerNames = from r in Formula1.GetChampion()
                where r.Country == "Italy"
                orderby r.Wins descending
                select new
                {
                    Name = r.FirstName + " " + r.LastName
                };
            var racerNamesAndStars = from r in Formula1.GetChampion()
                where r.Country == "Italy"
                orderby r.Wins descending
                select new
                {
                    LastName = r.LastName,
                    Starts = r.Starts
                };
            //Zip()方法
            var racers = racerNames.Zip(racerNamesAndStars, (first, second) => first.Name + ",starts:" + second.Starts);
            foreach (var racer in racers)
            {
                Console.WriteLine(racer);
            }

 9,使用Skip()方法和Take()方法分页

    Skip()方法:跳过序列中指定数量的元素,然后返回剩余的元素。

    Take()方法:从序列的开头返回指定数量的连续元素。

            int pageSize = 5;
            int numberPages = (int) Math.Ceiling(Formula1.GetChampion().Count/(double) pageSize);
            for (int page = 0; page < numberPages; page++)
            {
                Console.WriteLine($"Page {page+1}");
                var racers = (from r in Formula1.GetChampion()
                    orderby r.LastName, r.FirstName
                    select r.ToString()).
                    Skip(page*pageSize).Take(pageSize);
                foreach (var name in racers)
                {
                    Console.WriteLine(name);
                }
            }

输出(前三页):

Page 1
Fernando Alonso
Mario Andretti
Alberto Ascari
Jack Brabham
Jenson Button
Page 2
Jim Clark
Juan Manuel Fangio
Nino Farina
Emerson Fittipaldi
Kimi Green
Page 3
Mika Hakkinen
Lewis Hamilton
Mike Hawthorn
Damon Hill
Graham Hill

10,聚合操作符

    Count方法:

            var query = from r in Formula1.GetChampion()
                let numberYears = r.Years.Count()
                where numberYears >= 3
                orderby numberYears descending, r.LastName
                select new
                {
                    Name = r.ToString(),
                    TimesChampion = numberYears
                };
            foreach (var r in query)
            {
                Console.WriteLine($"{r.Name} {r.TimesChampion}");
            }

输出:

Michael Schumacher 7
Juan Manuel Fangio 5
Alain Prost 4
Jack Brabham 3
Niki Lauda 3
Nelson Piquet 3
Ayrton Senna 3
Jackie Stewart 3

    用Sum()方法计算一个国家赢得比赛的总次数

var countries =
                (from c in
                    from r in Formula1.GetChampion()
                    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}");
            }

输出:

UK 167
Germany 112
Brazil 78
France 51
Finland 42

11,转换操作符

    ToList()方法

            List<Racer> racers = (from r in Formula1.GetChampion()
                where r.Starts > 150
                orderby r.Starts descending
                select r).ToList();
            foreach (var racer in racers)
            {
                Console.WriteLine($"{racer} {racer:S}");
            }

输出:

Michael Schumacher 287
Jenson Button 208
Nelson Piquet 204
Alain Prost 197
Nigel Mansell 187
Fernando Alonso 177
Graham Hill 176
Niki Lauda 173
Jacques Villeneuve 165
Ayrton Senna 161
Mika Hakkinen 160

12,生成操作符

            var values = Enumerable.Range(1, 20);
            foreach (var item in values)
            {
                Console.Write($"{item} ");
            }

输出:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

13,表达式树看不懂

《C#高级编程》读书笔记(八):LINQ

标签:

原文地址:http://www.cnblogs.com/khjian/p/5654103.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!