语言集成查询
語言風格 > 標準查詢運算子 (Standard query operators)

System.Linq.Enumerable静态类声明了一套标准查询操作符（Standard Query Operators，SQO）方法集合。基本语法如下：
using (var db = new EntityContext())
 {
     var roles = from o in db.Users
                where o.Account == "Apollo"
                select o.Roles;
     …
 }
标准查询操作符和Lambda表达式的关系非常密切。编译器会将上述表达式转化为下述以Lambda表达式为参数的显式扩展方法调用序列：
using (var db = new EntityContext())
 {
     var roles = db.Users.Where(o => o.Account == "Apollo").Select(o => o.Roles);
 }
| 操作符 | 类别 | 语义 | 流利语法示例 | 查询表达式语法示例 |
| --- | --- | --- | --- | --- |
| Where | 筛选操作符(Restriction) | Predicate→bool | var user =  db.Users.Where( o => o.Roles != null);  |   var users =  from o in db.Users where o.Roles != null select o;  |
| Select | 投影操作符(Projection) | 将对象投影为一个匿名类型实例 TSource→TResult | var users =  db.Users.Select (o => new { o.Account, o.Password });  | var users =  from o in db.Users select new { o.Account, o.Password };  |
| SelectMany | 投影操作符(Projection) | 返回多行结果，用于多表的交叉连接（cross join） | Dim res = Employees.SelectMany(Function(e)   e.Family.Select(Function(c)c.name))  |  |
| Skip | 分块操作符(Partitioning) | 跳过前n个元素 | var users =  db.Users.OrderBy( o => o.Roles.Count ).Skip(10);  |  |
| SkipWhile | 分块操作符(Partitioning) | 跳过起始处使条件为真的所有元素 | var users =  db.Users.OrderBy( o => o.Roles.Count).SkipWhile( o => o.Roles == 3);  |  |
| Take | 分块操作符(Partitioning) | 返回开头之处的n个元素 | var users =  db.Users.OrderBy( o => o.Roles.Count).Take(5);  |  |
| TakeWhile | 分块操作符(Partitioning) | 返回起始处使条件为真的所有元素 | var users =  db.Users.OrderBy( o => o.Roles.Count).TakeWhile( o => o.Roles.Count == 3);  |  |
| Join | 连接操作符 | 内连接两个或多个表，仅限于Equals运算符 | var categoriesProducts =  from c in nWEntities.Categories join p in nWEntities.Products on c.CategoryID equals p.CategoryID into productsByCategoryID select new { c.CategoryName, productCount =  productsByCategoryID.Count() };  |  |
| GroupJoin | 连接操作符 | 类似于LEFT OUTER JOIN，右侧集合匹配于左侧集合键值的元素被分组 | From cust In customers Group  Join ord In orders  On cust.CustomerID   Equals ord.CustomerID  Into CustomerOrders = Group,     OrderTotal = Sum(ord.Total)  |  |
| Concat | 合并操作符 | 用于连接两个序列 | returnValue = firstSeq.Concat(secondSeq) |  |
| OrderBy | 排序操作符(Ordering) | 升序排列 TSource→TKey | var users =  db.Users.OrderBy( o => o.Roles.Count);  | var users =  from o in db.Users orderby o.Roles.Count select o;  |
| OrderByDescending | 排序操作符(Ordering) | 降序排列 | var users =  db.Users.OrderByDescending( o => o.Roles.Count);  | var users =  from o in db.Users orderby o.Roles.Count descending select o;  |
| ThenBy | 排序操作符(Ordering) | 只能对IOrderedEnumerable接口对象使用 |  |  |
| ThenByDescending | 排序操作符(Ordering) | 只能对IOrderedEnumerable接口对象使用 |  |  |
| Reverse | 排序操作符(Ordering) | 只能对IOrderedEnumerable接口对象使用 |  |  |
| GroupBy | 分组操作符 |  | var users =  db.Users.GroupBy( o => o.Roles.Count);  | var users =  from o in db.Users group o by o.Roles.Count into g select new { RoleCount = g.Key, Group = g };  |
| Distinct | 集合操作符 | 去重复 | var roles =  user.Roles.Distinct();  |  |
| Union | 集合操作符 | 集合并，还去重复 | var roles =  user1.Roles.Union( user2.Roles);  |  |
| Intersect | 集合操作符 | 集合交 | var roles =  user1.Roles.Intersect( user2.Roles);  |  |
| Except | 集合操作符 | 集合差 | var roles =  user1.Roles.Except( user2.Roles);  |  |
| AsEnumerable | 转换操作符 | 用于把一个IEnumerable的派生类型转化为IEnumerable类型 |  |  |
| AsQueryable | 转换操作符 | IEnumerable(Of T)转化为IQueryable(Of T). |  |  |
| ToArray | 转换操作符 | 转换为数组 |  |  |
| ToList | 转换操作符 | 转换为List |  |  |
| ToDictionary | 转换操作符 | 转换为一对一的字典（键-值对的集合） |  |  |
| ToLookup | 转换操作符 | 转换为一对多的字典（键-值集的集合） |  |  |
| OfType | 转换操作符 | 获取指定类型的元素组成一个数组 | object[] numbers = { null, 1.0,  "two", 3, "four", 5,  "six", 7.0 }; var doubles =  numbers.OfType<double>();  |  |
| Cast | 转换操作符 | 把序列的所有元素转换为指定类型 |  |  |
| SequenceEqual | 相等操作符 | 两个序列的元素依次相同返回真。 使用元素所属类的IEqualityComparer(Of T) 泛型界面做相等比较 |  |  |
| First | 元素操作符 | 返回序列第一个元素（或满足条件第一个元素），没有则异常 |  |  |
| FirstOrDefault | 元素操作符 | 返回序列第一个元素，没有则返回空或默认值 | var user =  db.Users.FirstOrDefault( o => o.Roles.Count == 3);  |  |
| Last | 元素操作符 | 返回序列最后一个元素，没有则异常 |  |  |
| LastOrDefault | 元素操作符 | 返回序列最后一个元素，没有则返回空或默认值 | var user =  db.Users.LastOrDefault( o => o.Roles.Count == 3);  |  |
| Single | 元素操作符 | 返回序列唯一元素，如果没有元素或多个元素则异常 |  |  |
| SingleOrDefault | 元素操作符 | 返回序列唯一元素，如果多个元素则异常 | var user = db.Users.SingleOrDefault(o => o.Account == "Apollo");  |  |
| ElementAt | 元素操作符 | 返回序列指定元素，失败则异常 |  |  |
| ElementAtOrDefault | 元素操作符 | 返回序列指定元素，失败则空或默认值 |  |  |
| DefaultIfEmpty | 元素操作符 | 返回序列，如果序列为空则返回元素的默认值 | For Each number As Integer  In numbers.DefaultIfEmpty()    output.AppendLine(number) Next  |  |
| All | 量词操作符 | 序列所有元素满足条件则为真 | var result  = db.Users.All( o => o.Roles.Count == 3);  |  |
| Any | 量词操作符 | 序列有一个元素满足条件则为真 | var result  = db.Users.Any( o => o.Roles.Count == 3);  |  |
| Contains | 量词操作符 | 是否包含一个元素 | var result =  db.Users.Where( o => o.Roles.Count == 3 ).Contains(user1);  |  |
| Count | 聚合统计操作符 | 计数，可选一个谓词 | var result  = db.Users.Count (o => o.Roles.Count == 3);  |  |
| LongCount | 聚合统计操作符 | 计数，返回Int64类型 |  |  |
| Sum | 聚合统计操作符 | 求和，可选对一个lambda函数表达式 | var result  = db.Users.Sum (o => o.Roles.Count);  |  |
| Min | 聚合统计操作符 | 最小值，可选对一个lambda函数表达式 | var result  = db.Users.Min (o => o.Roles.Count);  |  |
| Max | 聚合统计操作符 |  | var result  = db.Users.Max (o => o.Roles.Count);  |  |
| Average | 聚合统计操作符 |  | var result  = db.Users.Average (o => o.Roles.Count);  |  |
| Aggregate | 聚合统计操作符 | 参数为一个委托，在序列的每个元素上执行该委托。 委托的第一个参数为当前累计值，第二个参数为当前元素， 返回值为新的累计值 | Dim reversed As String =  words.Aggregate( Function(ByVal current,  ByVal word)  word & " " & current)  |  |
| equals/Equals | 关键字 | 用于Join子句 |  |  |
| from/From | 关键字 |  |  |  |
| in/In | 关键字 | 指出数据源 |  |  |
| into/Into | 关键字 | 用于Group By子句 |  |  |
| key | 关键字 | 用于Group By子句的无名类型 |  |  |
| let | 关键字 | 给表达式定义别名 | From prod In products  Let Discount =  prod.UnitPrice * 0.1  Where Discount >= 50  Select prod.ProductName,  prod.UnitPrice, Discount  |  |
| Group | 关键字 | 在GroupBy子句的Into中用于辨识分组结果 | From num In numbers  Group num By  remainder5 =  (num Mod 5) Into Group  |  |
| Range | 方法 | 产生一个整数序列 | From n In  Enumerable.Range(100, 50)  |  |
| Repeat | 方法 | 产生一个整数序列 | From n In   Enumerable.Repeat(7, 10)  |  |