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


    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	 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,表达式树看不懂

  • 相关阅读:
    restFul接口设计规范[仅供参考]
    Vue的router路由跳转传参——实现跳转时url不显示参数
    vue-cli(vue脚手架)搭建超详细教程
    Vue面试常见问题
    Ubuntu18.04安装时的一些问题
    仿BBS项目
    前端常用正则校验
    orm数据库查询优化及数据库三大设计范式总结
    SpringBoot+Git+Jenkins+Docker实现CI/CD
    Jenkins Pipeline+Maven+Gitlab持续集成构建问题集锦
  • 原文地址:https://www.cnblogs.com/khjian/p/5654103.html
Copyright © 2020-2023  润新知