LINQ基础(一)
LINQ(Language Integrated Query,语言集成查询),在C#语言中集成了查询语法,可以用相同的语法访问不同的数据源。
LINQ提供了不同数据源的抽象层,所以可以使用相同的语法。
这里主要介绍LINQ的核心原理和C#中支持C# LINQ查询的语言扩展。
1.语法
使用LINQ查询出来自巴西的所以世界冠军。这里可以使用List<T>类的FindAll()方法,但使用LINQ查询语法更简单
- 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);
- }
- }
变量query只指定了LINQ查询。该查询不是通过这个赋值语句执行的,而是使用foreach循环访问查询时执行的。
2.扩展方法
编译器会转换LINQ查询,以调用方法而不是LINQ查询。LINQ为IEnumerable<T>接口提供了各种扩展方法(扩展方法在http://www.cnblogs.com/afei-24/p/6703843.html介绍到),以便用户在实现了该接口的任意集合上使用LINQ查询。
定义LINQ扩展方法的一个类是System.Linq名称空间中的Enumerable。只需要导入这个名称空间,就打开了这个类的扩展方法的作用域。下面是Where()扩展方法的实现代码:
- public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source,Func<TSource,bool> predicate)
- {
- foreach(TSource item in source)
- {
- if(predicate(item))
- {
- yield return item;
- }
- }
- }
因为Where()作为一个泛型方法,所以它可以用于包含在集合中的任意类型。实现了IEnumerable<T>接口的任意集合都支持它。
3.推迟查询的执行
前面提到,在运行期间定义LINQ查询表达式时,查询不会运行。查询在迭代数据项时才会运行。
举个例子:
- 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);
- }
- }
输出:
因为查询在迭代时才执行,所以在第一次输出后有添加项再输出,会显示又添加的项。
但在调用方法ToArray(),ToList等方法时,不会延迟执行:
- static void NotDeferredQuery()
- {
- var names = new List<string> { "Nino", "Alberto", "Juan", "Mike", "Phil" };
- var namesWithJ = (from n in names
- where n.StartsWith("J")
- orderby n
- select n).ToList();
- 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);
- }
- }
输出:
下面是用到的类,后续的也需要用到这些代码。
- //这个类创建需要的列表
- public static class Formula1
- {
- private static List<Racer> racers;
- //返回一组赛车手
- public static IList<Racer> GetChampions()
- {
- if (racers == null)
- {
- racers = new List<Racer>();
- racers.Add(new Racer("Nino", "Farina", "Italy", , ,
new int[] { }, new string[] { "Alfa Romeo" }));- racers.Add(new Racer("Alberto", "Ascari", "Italy", , ,
new int[] { , }, new string[] { "Ferrari" }));- racers.Add(new Racer("Juan Manuel", "Fangio", "Argentina", , ,
new int[] { , , , , }, new string[] { "Alfa Romeo", "Maserati", "Mercedes", "Ferrari" }));- racers.Add(new Racer("Mike", "Hawthorn", "UK", , ,
new int[] { }, new string[] { "Ferrari" }));- racers.Add(new Racer("Phil", "Hill", "USA", , ,
new int[] { }, new string[] { "Ferrari" }));- racers.Add(new Racer("John", "Surtees", "UK", , ,
new int[] { }, new string[] { "Ferrari" }));- racers.Add(new Racer("Jim", "Clark", "UK", , ,
new int[] { , }, new string[] { "Lotus" }));- racers.Add(new Racer("Jack", "Brabham", "Australia", , ,
new int[] { , , }, new string[] { "Cooper", "Brabham" }));- racers.Add(new Racer("Denny", "Hulme", "New Zealand", , ,
new int[] { }, new string[] { "Brabham" }));- }
- return racers;
- }
- private static List<Team> teams;
- //返回一组冠军车队
- public static IList<Team> GetContructorChampions()
- {
- if (teams == null)
- {
- teams = new List<Team>()
- {
- new Team("Vanwall", ),
- new Team("Cooper", , ),
- new Team("Ferrari", , , , , , , , , ,
2000, , , , , , ),- new Team("BRM", ),
- new Team("Lotus", , , , , , , ),
- new Team("Brabham", , ),
- new Team("Matra", ),
- new Team("Tyrrell", ),
- new Team("McLaren", , , , , , , , ),
- new Team("Williams", , , , , , , , , ),
- new Team("Benetton", ),
- new Team("Renault", , ),
- new Team("Brawn GP", ),
- new Team("Red Bull Racing", , )
- };
- }
- return teams;
- }
- private static List<Championship> championships;
- //返回GetChampionships类型的集合
- public static IEnumerable<Championship> GetChampionships()
- {
- if (championships == null)
- {
- championships = new List<Championship>();
- championships.Add(new Championship
- {
- Year = ,
- First = "Nino Farina",
- Second = "Juan Manuel Fangio",
- Third = "Luigi Fagioli"
- });
- championships.Add(new Championship
- {
- Year = ,
- First = "Juan Manuel Fangio",
- Second = "Alberto Ascari",
- Third = "Froilan Gonzalez"
- });
- championships.Add(new Championship
- {
- Year = ,
- First = "Alberto Ascari",
- Second = "Nino Farina",
- Third = "Piero Taruffi"
- });
- championships.Add(new Championship
- {
- Year = ,
- First = "Alberto Ascari",
- Second = "Juan Manuel Fangio",
- Third = "Nino Farina"
- });
- championships.Add(new Championship
- {
- Year = ,
- First = "Juan Manuel Fangio",
- Second = "Froilan Gonzalez",
- Third = "Mike Hawthorn"
- });
- championships.Add(new Championship
- {
- Year = ,
- First = "Juan Manuel Fangio",
- Second = "Stirling Moss",
- Third = "Eugenio Castellotti"
- });
- championships.Add(new Championship
- {
- Year = ,
- First = "Juan Manuel Fangio",
- Second = "Stirling Moss",
- Third = "Peter Collins"
- });
- }
- return championships;
- }
- }
- //车手类
- [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 -;
- 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));
- }
- }
- }
- //获得冠军的车队
- [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; }
- }
- //获奖选手和年份
- public class Championship
- {
- public int Year { get; set; }
- public string First { get; set; }
- public string Second { get; set; }
- public string Third { get; set; }
- }
LINQ基础(一)的更多相关文章
- [.net 面向对象编程基础] (19) LINQ基础
[.net 面向对象编程基础] (19) LINQ基础 上两节我们介绍了.net的数组.集合和泛型.我们说到,数组是从以前编程语言延伸过来的一种引用类型,采用事先定义长度分配存储区域的方式.而集合是 ...
- LINQ基础概述
介绍LINQ基础之前,首说一下LINQ 的历史和LINQ是什么,然后说一下学习 LINQ要了解的东西和 LINQ基础语法 LINQ 的历史 从语言方面的进化 –委托 –匿名方法 –Lambda表达 ...
- LINQ基础(二)
本文主要介绍LINQ查询操作符 LINQ查询为最常用的操作符定义了一个声明语法.还有许多查询操作符可用于Enumerable类. 下面的例子需要用到LINQ基础(一)(http://www.cnblo ...
- LINQ基础(三)
一.并行LINQ System.Linq名称空间中包含的类ParallelEnumerable可以分解查询的工作,使其分布在多个线程上. 尽管Enumerable类给IEnumerable<T& ...
- Linq基础操作之Select,Where,OrderBy,ThenBy源码分析
Linq基础操作之Select,Where,OrderBy,ThenBy源码分析 二:Select 它是延迟执行.yield有得一拼,因为他们都是生成了一个枚举类. if (source is TSo ...
- Linq基础必备
1.linq基础必备之对象初始化器和匿名类型因果分析 3. 一:对象初始化器 1.就是在new的时候给公共属性赋值的一种方式 2. 在没有初始化器之前的时候,我们是怎么初始化的呢??? 1. 构造 ...
- 20.C#LINQ基础和简单使用(十一章11.1-11.2)
终于看到了第11章,之前虽然也有看过,但没有太仔细,在工作中也偶尔会使用,但不明白其中的原理,那现在就来讲讲LINQ,做一做书虫~~ 首先先了解下LINQ的三个要点: LINQ不能把非常复杂的查询表达 ...
- LINQ之路(1):LINQ基础
本文将从什么是LINQ(What).为什么使用LINQ(Why)以及如何使用LINQ(How)三个方面来进行说明. 1.什么是LINQ LINQ(Language Integrated Query)是 ...
- Linq基础知识小记四之操作EF
1.EF简介 EF之于Linq,EF是一种包含Linq功能对象关系映射技术.EF对数据库架构和我们查询的类型进行更好的解耦,使用EF,我们查询的对象不再是C#类,而是更高层的抽象:Entity Dat ...
- C#3.0新增功能09 LINQ 基础01 语言集成查询
连载目录 [已更新最新开发文章,点击查看详细] 语言集成查询 (LINQ) 是一系列直接将查询功能集成到 C# 语言的技术统称. 数据查询历来都表示为简单的字符串,没有编译时类型检查或 Inte ...
随机推荐
- MySQL从库忽略某些错误
z熬配置MySQL主从同步的时候常常会因为主库的中SQL语句的错误造成从库的同步出现错误,一旦从库同步出现错误就会造成同步的卡壳影响后续的同步: 可以在从库的配置文件中加入如下的参数,使从库可以自动忽 ...
- pyqt样式表语法笔记(中)
pyqt样式表语法笔记(中) pyqt QSS python 样式表 一.弹窗 在日常的各种桌面软件的使用中,我们都会碰到弹窗.例如注册,登录的时候,会有相应的信息弹窗,这里就以信息收集弹窗为例进行弹 ...
- 浅谈MVC缓存
缓存是将信息放在内存中以避免频繁访问数据库从数据库中提取数据,在系统优化过程中,缓存是比较普遍的优化做法和见效比较快的做法. 对于MVC有Control缓存和Action缓存. 一.Control缓存 ...
- Servlet实现的三种方式
实现Servlet的三种方式:一个实现,两个继承 /*========================================== * servlet的执行过程: * 1.创建servlet对 ...
- response.getWriter().write()与out.print()的区别(转)
1.首先介绍write()和print()方法的区别: (1).write():仅支持输出字符类型数据,字符.字符数组.字符串等 (2).print():可以将各种类型(包括Object)的数据通 ...
- webix .datatable 表格分页
grid表格返回参数大都是 以下这种格式(参数名可能不一样) { data:[{...},{...} ...], count:39 } webix的参数格式为 { data:[{...},{...}, ...
- 【Electron】Electron开发入门(三):main process和web page 通信
一.main process 和 web page 通信 electron框架主进程(Main Process)与嵌入的网页(web page,也就是renderer process)之间的通信 Ma ...
- Python之路-awk文本处理
作业一:整理博客,内容包含awk.变量.运算符.if多分支 一.awk 1.awk是一个优秀的文本处理工具,多用来处理含有特殊分隔符的内容 常见用法 awk -F: {print $1,$4} 作业 ...
- 《连载 | 物联网框架ServerSuperIO教程》- 18.集成OPC Client,及使用步骤
1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...
- java 基础知识九 类与对象
java 基础知识九 类与对象 1.OO(Object–Oriented )面向对象,OO方法(Object-Oriented Method,面向对象方法,面向对象的方法)是一种把面向对象的思想应 ...