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 ...
随机推荐
- 检测Windows程序的内存和资源泄漏之原生语言环境
最近接连收到大客户的反馈,我们开发的一个软件,姑且称之为App-E吧,在项目规模特别大的情况下,长时间使用会逐渐耗尽内存,运行越来越缓慢,软件最终崩溃.由于App-E是使用混合语言开发的,主界面使用C ...
- CSS常见兼容性问题总结
原文链接:渔人码头 http://www.cnblogs.com/imwtr/p/4340010.html?utm_source=tuicool&utm_medium=referral 浏览器 ...
- 我的Python之路【第一篇】:Python简介和入门
1.搭建Python环境 windows下搭建python环境 1.下载安装包 2.Windows中Python的安装包是后缀名为msi的安装包,直接双击下一步即可 3.Windwos环境下默认的安装 ...
- pyqt系列原创入门教程
pyqt4入门教程 python pyqt4 PyQt是一个创建GUI应用程序的工具包.它是Python编程语言和Qt库的成功融合.Qt库是目前最强大的库之一. 通过pyqt可以实现很多我们想要的功能 ...
- 基于ThinkPHP 5.0与Vue.JS 2.x的前后端开源开发框架VueThink
VueThink 项目介绍 VueThink是一套基于Vue全家桶(Vue2.x + Vue-router2.x + Vuex)+ Thinkphp的前后端分离框架. 脚手架构建也可以通过vue官方的 ...
- js中的this关键字,setTimeout(),setInterval()的执行过程
var test1 = { name: 'windseek1', showname: function () { console.log(this.name); } } var test2 = { n ...
- trigger和triggerhandler的区别
1. trigger会触发默认行为2. trigger会触发所有元素的模拟事件,而triggerHandler只触发一次3. trigger可以链式操作,triggerHandler不能4. trig ...
- C# Task 源代码阅读(1)
平时我们开发中,经常使用Task,后续的.net版本种很多都和Task有关,比如asyn,await有了Task 我们很少就去关注Thread 了.Task 给我们带来了很多的便利之处.是我们更少的去 ...
- Math.pow用法及实现探究
pow函数在java.lang.Math类中,是求次方的函数,定义为: public static double pow(double a, double b): 即求a的b次方,例如: public ...
- jQ伪类选择器
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...