9、Lambda表达式
[1]Lambda表达式缩写推演,如下图:
[2]Lambda语句:=>右边有一个语句块(大括号"{}");Lambda表达式:=>右边只有一个表达式。
[3]Lambda本身无类型,不可赋值给var变量;
[4]编译时会生成一个静态方法,然后再实例化成委托传递使用;
Lambda详见:Lambda表达式
10、标准查询运算符(SQO)
"标准查询运算符"是组成语言集成查询 (LINQ) 模式的方法。标准查询运算符提供了包括筛选、投影、聚合、排序等功能在内的查询功能。
这意味着可以使用静态方法语法或实例方法语法来调用它们。
Queryable类定义两个类似的方法(Cast<TResult>(IQueryable)和 OfType<TResult>(IQueryable)),这些方法在类型为 Queryable的对象上运行。
返回序列的方法会延迟查询执行,并返回一个可枚举的对象。
对于在内存中集合上运行的方法(即扩展 IEnumerable<T>的那些方法),返回的可枚举对象将捕获传递到方法的参数。在枚举该对象时,将使用查询运算符的逻辑,并返回查询结果。
查询处理由源 IQueryable<T>对象处理。
标准查询语法关键字:
from 子句开头。
from子句中引用的数据源的类型必须为 IEnumerable、IEnumerable<T>或一种派生类型(如 IQueryable<T>)。
例子10-1:
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
// Create the query.
// lowNums is an IEnumerable<int>
var lowNums = from num in numbers
where num < 5
select num;
[2]where 子句:
并返回满足指定条件的元素。
num < 5 是应用于每个元素的谓词。
[3]select 子句:
select 子句可以指定将在执行查询时产生的值的类型。
select 子句本身中的所有表达式。
select 子句或 group子句结束。
[4]group...by...子句:
(1)返回一个 IGrouping<TKey, TElement>对象序列,这些对象包含零个或更多个与该组的键值匹配的项 。
var stu0 =
from student in students
group student by student.Last[0];
(2)如果您想要对每个组执行附加查询操作,则可以使用 "into"上下文关键字指定一个临时标识符。group 子句结束该查询,如下所示:
var stu1 =
from student in students
group student by student.Last[0] into g
orderby g.Key
select g;
(3)可通过orderby...thenby...指定次要排序
[5]into:可以使用 into 上下文关键字创建一个临时标识符,以便将 group、join 或 select 子句的结果存储到新的标识符中。
string[] words = { "apples", "blueberries", "oranges", "bananas", "apricots"};
var wordGroups =
from w in words
group w by w[0] into fruitGroup
where fruitGroup.Count() >= 2
select new { FirstLetter = fruitGroup.Key, Words = fruitGroup.Count() };
[6]orderby 子句:
(1)可使返回的序列或子序列(组)按升序或降序排序。
但是,只能通过基于方法的语法使用它。
string[] fruits = { "cherry", "apple", "blueberry" };
IEnumerable<string> sortAscendingQuery =
from fruit in fruits
orderby fruit //"ascending" is default
select fruit;
[7]...join...on...equals...子句:
(1)使用 join 子句可以将来自不同源序列并且在对象模型中没有直接关系的元素相关联。
(2)唯一的要求是每个源中的元素需要共享某个可以进行比较以判断是否相等的值。
(3)
join子句执行的所有联接都是同等联接。
(5)join子句的输出形式取决于所执行的联接的具体类型。
(6)联接类型:内部联接; 分组联接; 左外连接;
var innerJoinQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID
select new { ProductName = prod.Name, Category = category.Name }; //
含有 into 表达式的 join 子句称为分组联接。
var innerGroupJoinQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID into prodGroup
select new { CategoryName = category.Name, Products = prodGroup };
在左外部联接中,将返回左侧源序列中的所有元素,即使它们在右侧序列中没有匹配的元素也是如此。null 作为任何引用类型的默认值,也可以指定用户定义的默认类型。
var leftOuterJoinQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID into prodGroup
from item in prodGroup.DefaultIfEmpty(new Product { Name = String.Empty, CategoryID = 0 })
select new { CatName = category.Name, ProdName = item.Name };
[8]let 子句:
但如果该范围变量存储的是可查询的类型,则可以对其进行查询。
string[] strings =
{
"A penny saved is a penny earned.",
"The early bird catches the worm.",
"The pen is mightier than the sword."
};
var earlyBirdQuery =
from sentence in strings
let words = sentence.Split(' ')
from word in words
let w = word.ToLower()
where w[0] == 'a' || w[0] == 'e'
|| w[0] == 'i' || w[0] == 'o'
|| w[0] == 'u'
select word;
[9]ascending 和 descending
(1)ascending :升序是默认排序顺序,所以您无须指定它。
(2)descending :降序
IEnumerable<string> sortDescendingQuery =
from vegetable in vegetables
orderby vegetable descending
select vegetable;
[10]in:
该上下文关键字可在下面三种上下文中使用:
from category in categories join prod in products on category.ID equals prod.CategoryID
(3)泛型接口和委托中的泛型类型参数。
11、LINQ查询表达式
本质:从Reflector中可以看到Linq最后都别转换成了标准查询语句。
[1]linq类似于Sql语句,以"from"子句开始,以"select"或"group...by..."子句结束;
[2]输出是一个IEnumerable<T>或 IQueryable<T>集合;"T的类型"是由select或group子句推断出来的。
class LINQQueryExpressions
{
static void Main()
{
// Specify the data source.
int[] scores = new int[] { 97, 92, 81, 60 };
// Define the query expression.
IEnumerable<int> scoreQuery =
from score in scores
where score > 80
select score;
// Execute the query.
foreach (int i in scoreQuery)
{
Console.Write(i + " ");
}
}
}