LINQ之查询语法--from子句
LINQ查询基本操作包括以下主要关键字:
--from子句
--where子句
--select子句
--group子句
--into子句
--orderby子句
--join子句
--let子句
LINQ示例:
//1. data source int[] linqTestArray = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; //2. query expression var query = from linqTest in linqTestArray where linqTest % 2 == 0 select linqTest; //3. output foreach (int i in query) { Console.WriteLine(i); } Console.ReadLine();
从上面的例子不难看出,LINQ查询操作包含以下三部分:
1) 获取数据源,LINQ的数据源必须是实现IEnumerable接口对象集合
2) 定义查询表达式,类似SQL
3) 输出查询结果,查询变量只定义了查询命令,并没有执行,而是延迟到foreach执行,当然,我们也可以强制立即执行。
查询表达式语法:
查询表达式必须满足以下语法规则:
1)查询必须以from子句开始;
2) 剩余的查询表达式可以包含0个或多个from,let或where子句;
3) 查询表达式也可以包含orderby子句,可以是ascending或descending,与SQL不一样的是,升序或降序都必须是单词的全写,而不能用asc或desc
4) 其后应该跟随一个select或group子句
5) 其后可以有其他的操作
from子句
对于简单的from子句,其实没什么好讲的,跟我们写SQL文是差不多的。下面着重介绍复合from子句和使用多个from子句执行连接。
--复合from子句
当数据源中的每个元素本身就是一个序列,或者数据源中的元素包含序列,此时,我们可以通过复合from子句来访问单个数据源中的集合。
举个例子,一个班级中的学生是一个序列,每个学生所有的成绩列表又是一个序列,假设我们要查找出所有不及格学生及其不及格的分数,我们可以用以下LINQ查询语句来获取这一列表:
//定义数据源 List<Student> students = new List<Student> { new Student{Name = "Terry",Scores = new List<int>{98,88,93,75,82}}, new Student{Name = "Tina",Scores = new List<int>{85,99,87,93,97}}, new Student{Name = "Linda",Scores = new List<int>{57,100,83,89,92}}, new Student{Name = "Leon",Scores = new List<int>{100,98,72,77,84}}, new Student{Name = "Echo",Scores = new List<int>{79,80,97,55,88}} }; //定义查询表达式,找出不及格的学生及其分数 var scoreQuery = from student in students from score in student.Scores where score < 60 select new {student.Name, score}; //输出结果 foreach (var query in scoreQuery) { Console.WriteLine("Student:{0} Score:{1}",query.Name,query.score); }
NOTE: 定义数据源的部分采用了对象/集合初始化器,不熟悉的朋友可以参照LINQ学前准备之对象集合初始化器
我们着重来看一下查询表达式
首先,我们从students这个数据源中进行查询,student为范围变量,代表每一个student,然后,我们将该范围变量的Scores又作为第二个from的数据源,查找出其值<60的那些score。
查询出来的结果为:
--使用多个from子句执行连接
使用多个from子句连接查询,可以从多个独立的数据源生成补充查询。类似于SQL的join,当然,LINQ也有join语法,他跟多个from的连接语法上是不一样的,我们稍后会介绍join子句。
假设我们有一个Category集合,还有一个Product集合,Product是属于某个Category的,为了获取Category下所有的Product,我们可以定义如下查询:
List<Category> categories = new List<Category> { new Category{Id = 1,Name = "Food"}, new Category{Id = 2,Name = "Toys"}, new Category{Id = 3,Name = "Fruit"} }; List<Product> products = new List<Product> { new Product{ProductId = 201,ProductName = "Chuckit",CategoryId = 2}, new Product{ProductId = 202,ProductName = "SafeMade",CategoryId = 2}, new Product{ProductId = 101,ProductName = "Taste",CategoryId = 1}, new Product{ProductId = 102,ProductName = "Canidae",CategoryId = 1}, new Product{ProductId = 103,ProductName = "Flavor",CategoryId = 1} }; var productList = from category in categories from product in products where product.CategoryId == category.Id select new {category.Name, product.ProductName}; foreach (var product in productList) { Console.WriteLine("{0}----{1}",product.Name,product.ProductName); }
我们得到的结果为:
在这个例子中,我们通过2个数据源categories和products进行查询,并按照categoryid进行连接。
由于Fruit这个Category下没有产品,因此没有被查找出来。
需要跟SQL区分开来的是,这里用的是C#的语法,因此做对等比较的时候应该用”==”而不是”=”。
To be continue…
参考:webcast《跟我一起学Visual Studio 2008系列课程》