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; }
}

最新文章

  1. 通过trie树单词自动补全(二)
  2. 黑马程序员_ C语言基础之指针(三)
  3. Oracle中的NVL函数
  4. 【原】iOS学习38网络之数据解析
  5. python 之ConfigParser
  6. 在IIS7中使用ARR(Application Request Routing)反向代理虚拟目录到Nodejs站点
  7. Hibernate-入门教程
  8. 高并发简单解决方案————redis队列缓存+mysql 批量入库(ThinkPhP)
  9. [原博客] POI系列(2)
  10. OPENCV
  11. [IOI1999]花店橱窗布置(DP路径记录)
  12. 经典switch
  13. spring-session 共享
  14. 前端Mahsup异步依赖方式不能做业务数据依赖
  15. Redis+TwemProxy(nutcracker)集群方案部署记录
  16. CentOS下防御或减轻DDoS攻击方法(转)
  17. js的各种正则表达式
  18. chrome-extension &amp; inject.js
  19. 教你摆脱低级程序猿 项目中cocopads的安装使用
  20. Spark记录-Scala介绍

热门文章

  1. Solr5.2.1+Zookeeper3.4.8分布式集群搭建
  2. iOS开发之iOS程序的启动过程
  3. 开启Tomcat远程调试(转)
  4. Failed to connect to Xilinx hw_server. Check if the hw_server is running and correct TCP port is used.
  5. 关于commonjs,AMD,CMD之间的异同
  6. GWT开端
  7. jquery练习之瀑布流
  8. 【微信开发】PHP中奖概率经典算法实例
  9. 从零开始用 Flask 搭建一个网站(一)
  10. python urllib模块