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基础(一)的更多相关文章

  1. [.net 面向对象编程基础] (19) LINQ基础

    [.net 面向对象编程基础] (19)  LINQ基础 上两节我们介绍了.net的数组.集合和泛型.我们说到,数组是从以前编程语言延伸过来的一种引用类型,采用事先定义长度分配存储区域的方式.而集合是 ...

  2. LINQ基础概述

    介绍LINQ基础之前,首说一下LINQ 的历史和LINQ是什么,然后说一下学习 LINQ要了解的东西和 LINQ基础语法   LINQ 的历史 从语言方面的进化 –委托 –匿名方法 –Lambda表达 ...

  3. LINQ基础(二)

    本文主要介绍LINQ查询操作符 LINQ查询为最常用的操作符定义了一个声明语法.还有许多查询操作符可用于Enumerable类. 下面的例子需要用到LINQ基础(一)(http://www.cnblo ...

  4. LINQ基础(三)

    一.并行LINQ System.Linq名称空间中包含的类ParallelEnumerable可以分解查询的工作,使其分布在多个线程上. 尽管Enumerable类给IEnumerable<T& ...

  5. Linq基础操作之Select,Where,OrderBy,ThenBy源码分析

    Linq基础操作之Select,Where,OrderBy,ThenBy源码分析 二:Select 它是延迟执行.yield有得一拼,因为他们都是生成了一个枚举类. if (source is TSo ...

  6. Linq基础必备

    1.linq基础必备之对象初始化器和匿名类型因果分析   3. 一:对象初始化器 1.就是在new的时候给公共属性赋值的一种方式 2. 在没有初始化器之前的时候,我们是怎么初始化的呢??? 1. 构造 ...

  7. 20.C#LINQ基础和简单使用(十一章11.1-11.2)

    终于看到了第11章,之前虽然也有看过,但没有太仔细,在工作中也偶尔会使用,但不明白其中的原理,那现在就来讲讲LINQ,做一做书虫~~ 首先先了解下LINQ的三个要点: LINQ不能把非常复杂的查询表达 ...

  8. LINQ之路(1):LINQ基础

    本文将从什么是LINQ(What).为什么使用LINQ(Why)以及如何使用LINQ(How)三个方面来进行说明. 1.什么是LINQ LINQ(Language Integrated Query)是 ...

  9. Linq基础知识小记四之操作EF

    1.EF简介 EF之于Linq,EF是一种包含Linq功能对象关系映射技术.EF对数据库架构和我们查询的类型进行更好的解耦,使用EF,我们查询的对象不再是C#类,而是更高层的抽象:Entity Dat ...

  10. C#3.0新增功能09 LINQ 基础01 语言集成查询

    连载目录    [已更新最新开发文章,点击查看详细] 语言集成查询 (LINQ) 是一系列直接将查询功能集成到 C# 语言的技术统称. 数据查询历来都表示为简单的字符串,没有编译时类型检查或 Inte ...

随机推荐

  1. 开发检测MySQL主从同步插件

    Nagios的状态码 OK 退出码0,表示正常工作 WARNING  退出码1,表示处于警告阶段 CRITICAL    退出码2,表示处于紧急状态,严重状态 UNKOEN   退出码3,表示无法获取 ...

  2. 基于HBase的手机数据备份系统 .

    基于HBase实现的手机数据备份系统,实现了手机关键信息的备份,如短信.联系人等. 包括服务器端(Server)和客户端(Client) Server运行环境:Hadoop+HBase+Tomcat ...

  3. Spring:利用PerformanceMonitorInterceptor来协助应用性能优化

    前段时间对公司产品做性能优化,如果单依赖于测试,进度就会很慢.所以就通过对代码的方式来完成,并以此来加快项目进度.具体的执行方案自然就是要知道各个业务执行时间,针对业务来进行优化. 因为项目中使用了S ...

  4. 转载linux c语言程序的Makefile编写

    对于程序设计员来说,makefile是我们绕不过去的一个坎.可能对于习惯Visual C++的用户来说,是否会编写makefile无所谓.毕竟工具本身已经帮我们做好了全部的编译流程.但是在Linux上 ...

  5. webix .datatable 表格分页

    grid表格返回参数大都是 以下这种格式(参数名可能不一样) { data:[{...},{...} ...], count:39 } webix的参数格式为 { data:[{...},{...}, ...

  6. 树莓派Raspberry中成功安装RobotFramework+Selenium

    [原创链接]:http://www.cnblogs.com/atsats/p/6666848.html 一般RobotFramework都是安装在Windows/Linux的PC机上,这里将简单介绍在 ...

  7. Selenium测试专项一班隆重开班

    Selenium测试专项一班隆重开班 应广大测试技术人员要求,以及企业技术需求.Selenium提前一周开课了,只针对合作的每家企业提供1-2个参训名额.预计培训60人次.但报名人数却远远超出我们预期 ...

  8. 老李推荐:第2章1节《MonkeyRunner源码剖析》了解你的测试对象: NotePad应用简介

    老李推荐:第2章1节<MonkeyRunner源码剖析>了解你的测试对象: NotePad应用简介   本书脚本相关的示例常会用到Android SDK自带的NotePad这个应用,所以这 ...

  9. 各位Coder看过来

    为了丰富博客内容,也为了解决一些实际的问题,现准备出一系列博文,内容为各位回复评论指明需要的知识点,将在近期为你解决并提供还算精要的讲解:评论内容要求 Coder:+需要的技术内容.技术内容不限领域, ...

  10. Maven项目搭建(三):Maven直接部署项目

    上一章给大家讲解了如何使用Maven搭建SSM框架项目.   这次给大家介绍一下怎么使用Maven直接部署项目.   Maven直接部署项目  1.新建系统变量CATALINA_HOME,值为:Tom ...