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

时间: 2024-08-06 03:41:19

《C#高级编程》读书笔记(八):LINQ的相关文章

C++Windows核心编程读书笔记

转自:http://www.makaidong.com/%E5%8D%9A%E5%AE%A2%E5%9B%AD%E6%96%87/71405.shtml "C++Windows核心编程读书笔记": 关键词:c++windows 核心 编程 读书笔记 这篇笔记是我在读<windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的思考和对实现的推断,因此不少条款和windows实际机制可能有出入,但应该是合理的.开头几章由于我追求简洁

java 并发编程读书笔记

1.同步容器,同步容器包括Vector和HashTable,是早期jdk的一部分.另一部分是同步包装类,以Collections.synchronizedxxx的工厂方法创建. 2.同步容器虽然是线程安全的,但是对于复合操作,有时你可能需要加上额外的客户端加锁进行保护,即对于使用这些容器的客户端代码,如果存在复合操作,还是可能存在风险. 3.例如check-and-act操作.循环中的元素操作等,如果在客户端代码中没有额外的锁,都会发生意想不到的问题. 4.造成这些的问题都可以通过在客户端加锁来

TCP/IP网络编程读书笔记-简单的套接字编程(1)

在linux和windows下都是通过套接字编程进行网络编程.不同的系统上通信有部分差别,现在刚开始学习,给自己学习的时候一个总结. 一,socket函数的套接字步骤 第一,linux网络编程中接受连接请求(服务器端)套接字的四个步骤: 1)调用socket函数创建套接字 2)调用bind函数分配IP地址和端口号 3)调用listen函数转为可接收请求状态 4)调用accept函数受理连接请求 第二,linux网络编程中请求连接(客户端)套接字的两个步骤: 1)调用socket函数创建套接字 2

UNIX环境高级编程学习笔记(第一章UNIX基础知识)

总所周知,UNIX环境高级编程是一本很经典的书,之前我粗略的看了一遍,感觉理解得不够深入. 听说写博客可以提高自己的水平,因此趁着这个机会我想把它重新看一遍,并把每一章的笔记写在博客里面. 我学习的时候使用的平台是Windows+VMware+debian,使用secureCRT来连接(可以实现多个终端连接). 因为第一章是本书大概的描述,所以第一章的我打算写得详细一点,而且书本的原话占的比例会比较多,重点的东西会用粗体显示出来. 1.1  引言 所有操作系统都为他们所运行的程序提供服务.典型的

javascript高级编程学习笔记(二)

写读书笔记的好处在于加深记忆,前一篇总结了编程中创建的对象的几种方式,以及常用的方式,这一篇总结实现继承的方式: 1.对象冒充: function ClassA(sColor) { this.color = sColor; this.sayColor = function () { alert(this.color); }; } function ClassB(sColor, sName) { this.newMethod = ClassA; this.newMethod(sColor); de

oracle sql 高级编程 历史笔记整理

20130909 周一 oracle sql 开发指南 第7章 高级查询 1.层次化查询select level,ttt.*,sys_connect_by_path(ttt.col1,',') from ttt start with .. Connect by prior -因为先建立树,再进行where过滤的.在where中过滤和在cooonect by中过滤是不一样的. 2.rollup cube高级查询 select grouping(col1) .. From ttt group by

《C#高级编程》笔记系列第三弹

我们在开发WinForm时,经常会看到partial关键字,比如,我们新建一个Windows Form时,后台代码自动添加如下: 1 public partial class Form1 : Form2 {3     public Form1()4     {5         InitializeComponent();6     }7 } <C#高级编程>书中说明:partial关键字允许把类.结构或接口放在多个文件中.一般情况下,一个类存储在单个文件中,但有时,多个开发人员需要访问同一个

WCF服务编程 读书笔记——第1章 WCF基础(1)

第1章 WCF基础 本章主要介绍WCF的基本概念.构建模块以及WCF体系架构,以指导读者构建一个简单的WCF服务.从本章的内容中,我们可以了解到WCF的基本术语,包括地址(Address).绑定(Binding).契约(Contract)和终结点(Endpoint):了解如何托管服务,如何编写客户端代码:了解WCF的相关主题,诸如进程内托管(In-Proc Hosting)以及可靠性的实现.即使你已经熟知WCF的基本概念,仍然建议你快速浏览本章的内容,它不仅能够巩固你的已有知识,而且本章介绍的一

pthon核心编程-读书笔记:知识点摘录与总结(方便理解和快速记忆)

Python 中的列表(大小可变的数组)和字典(哈希表)就是内建于语言本身的.在核心语言中提供这些重要的构建单元,可以鼓励人们使用它们, 缩短开发时间与代码量,产生出可读性更好的代码.C不提供, c++功能不够简洁. 面向对象, 可升级:Python 提倡简洁的代码设计.高级的数据结构和模块化的组件,确保灵活性. 一致性并缩短必要的调试时间 扩展性:兼容扩展c和java 易读写,易维护 健壮性:Python 提供了"安全合理"的退出机制, Python由于错误崩溃,解释程序就会转出一个

C#高级编程六十七天----LINQ提供程序

LINQ提供程序 .NET3.5包含了几个LINQ提供程序. LINQ提供程序为特定的数据源实现了标准的查询操作符. LINQ提供程序也许会实现LINQ定义的更多扩展方法,但至少要实现标准操作符. LINQ to XML 不仅实现了专门用于XML 的方法,还实现了其他方法,例如System.Xml.Linq 命名空间的Extensions类定义的方法Elements(),Descendants 和Ancestors. LINQ提供程序的实现方案是根据命名空间和第一个参数的类型来实现的. 实现扩展