从应用程序的角度来看,原始源数据的特定类型和结构并不重要。 应用程序始终将源数据视为
IEnumerable<T>
或
IQueryable<T>
集合。数据库中一行就是一个可以枚举序列。
ints.Where(p => p % 2 == 0).ToArray(); p就是一个序列,p可以式数据库中的行,也可以式数组中item,也可式一个对象。
LINQ查询时有两种语法可供选择:
查询表达式语法(Query Expression):使用查询运算符;
流利语法(Fluent Syntax):利用System.Linq.Enumerable类中定义的扩展方法和Lambda表达式方式进行查询。
CLR本身并不理解查询表达式语法,它只理解流利语法。编译器负责把查询表达式语法编译为流利语法。
int[] ints={1,2,3,4};
var result = ints.Where(p => p % 2 == 0).ToArray();
对比流利语法和C#的传统语法:
// extension methods make LINQ elegant
IEnumerable<string> query = names
.Where(n => n.Contains("a"))
.OrderBy(n => n.Length)
.Select(n => n.ToUpper());
// static methods lose query's fluency
IEnumerable<string> query2 =
Enumerable.Select(
Enumerable.OrderBy(
Enumerable.Where(names, n => n.Contains("a")
), n => n.Length
), n => n.ToUpper()
标准的查询运算符(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);
LINQ的各式言語支援度
操作符类别语义流利语法示例查询表达式语法示例
Where
筛选操作符(Restriction)
Predicate→bool
var user =
db.Users.Where(
o => o.Roles != null);
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()
For Each number As Integer
In numbers.DefaultIfEmpty()
output.AppendLine(number)