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. Android getAttributeIntValue()详解-霞辉

    经常使用getAttributeIntValue()方法,但是大多使用的形式是attrs.getAttributeFloatValue(null, "xxx", 0);只是在中间传 ...

  2. MySQL二进制日志总结

    二进制日志简单介绍 MySQL的二进制日志(binary log)是一个二进制文件,主要用于记录修改数据或有可能引起数据变更的MySQL语句.二进制日志(binary log)中记录了对MySQL数据 ...

  3. python编码问题之\"encode\"&\"decode\"

    python encode decode 编码 decode的作用是将其他编码的字符串转换成unicode编码,如str1.decode('gb2312'),表示将gb2312编码的字符串str1转换 ...

  4. 浩哥解析MyBatis源码(三)——Transaction事务模块

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6634151.html 1.回顾 之前介绍了Environment环境类,这其实是一个单例类 ...

  5. java里的日期时间

    为了更好理解java的日期时间类,在这里我们先介绍一下关于历法.标准时间的一些概念. 历法有很多种,我们大中华上下五千年,自然也有自己的历法,生活中我们通常把自己传统的历法叫做农历,也有人叫它阴历或夏 ...

  6. 通过哨兵机制实现Redis主从配置以及java调用

    Redis版本:3.0.7 操作环境:Linux 一.redis 主从配置的作用是什么 redis主从配置,配置master 只能为写,slave只能为读,在客户端对poolconnect请求时候,, ...

  7. IOS开发创建开发证书及发布App应用(二)——创建证书

    2. 创建证书 证书分为两种,一种是开发者证书,主要是用来真机调试的 另一种就是发布证书,就是用来发布应用的, 最好是两种都要下载,不然编译时候可能报错,我猜想可能苹果怕你没用真机调试 创建证书分为两 ...

  8. Java进阶之多线程

    多线程 多线程(multiple thread)是计算机实现多任务并行处理的一种方式. 在单线程情况下,计算机中存在一个控制权,并按照顺序依次执行指令.单线程好像是一个只有一个队长指挥的小队,整个小队 ...

  9. nosql使用感受

    最近一个项目尝试了使用ssdb(一个类似于redis的数据结构数据库),主要感受有几点: 优势 nosql的无模式在修改和插入时很方便,不需要预先新建表或者修改表结构来新加字段,只需要代码里面使用就行 ...

  10. 4.熟悉Java基本类库系列——Java 正则表达式类库

    正则表达式语法结构图: Java正则表达式类库结构图: Java典型例子 1.String类 matches()方法 判断字符串是否符合特定正则表达式 @Test public void testRe ...