1)。查询执行的时机
1.查询分为以下三步:获取数据源、定义查询、执行查询;
2.定义查询后,查询直到需要枚举结果时才被真正执行,这种方式称为“延迟执行(deferred execution)”;
3.当查询方法返回单一值时,查询立即执行;
因此,可以通过以下技巧在定义查询时就强制执行查询
var even = numbers
.Where(p => p % 2 == 0)
.Select(p =>
{
Console.WriteLine("Hi! " + p.ToString());
return p;
}).Count();
2)。 LINQ查询存在以下两种形式
1. Method Syntax, 查询方法方式
主要利用 System.Linq.Enumerable 类中定义的扩展方法和 Lambda 表达式方式进行查询
2. Query Syntax, 查询语句方式
一种更接近 SQL 语法的查询方式
可读性更好
//查询语句
int[] numbers = new int[] { 6, 4, 3, 2, 9, 1, 7, 8, 5 };
var even = from number in numbers
where number % 2 == 0
orderby number descending
select number;
//查询方法
int[] numbers = new int[] { 6, 4, 3, 2, 9, 1, 7, 8, 5 };
var even = numbers
.Where(p => p % 2 == 0)
.OrderByDescending(p => p)
.Select(p => p);
两者的执行效果完全一样;
3)。 查询语句vs查询方法
查询语句与查询方法存在着紧密的关系
CLR本身并不理解查询语句,它只理解查询方法
编译器负责在编译时将查询语句翻译为查询方法
大部分查询方法都有对应的查询语句形式:如 Select() 对应 select 、 OrderBy() 对应 orderby
部分查询方法目前在C#中还没有对应的查询语句:如 Count()和Max() 这时只能采用以下替代方案
查询方法
查询语句 + 查询方法的混合方式;
一般情况下,建议使用可读性更好的查询语句
高级查询方法:
聚合类:
Count,Max/Min,Average
排序类:
ThenBy
分区类:
Take,TakeWhile,Skip,SkipWhile
集合类:
Distinct
生成类:
Range, Repeat
4)。聚合类查询方法
Count 返回集合项的数目
Max/Min 返回集合中的最大值/最小值
Average 返回集合的平均值
Sum 返回集合的总和
示例:int count = (from p in foxRiver8
where p.Age <= 30
select p).Count(); (其他情况类似)
5) . 排序类查询方法
ThenBy 提供复合排序条件
注意:ThenBy查询方法属于查询方法语句所有;查询语句使用orderby排序;
//查询方法
示例:var q = foxRiver8
.OrderBy(p => p.FirstName)
.ThenBy(p => p.LasName)
.ThenBy(p => p.Age);
//查询语句
示例: var q = from p in foxRiver8
orderby p.FirstName, p.LasName, p.Age
select p;
6) . 分区类查询方法
Take 提取指定数量的项
Skip 跳过指定数量的项并获取剩余的项
TakeWhile 根据指定条件提取项
SkipWhile 根据指定条件跳过项
示例:int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var q = numbers.Skip(1).Take(3);
foreach (var item in q) 跳过前1条记录,连续提取3条记录,得到2,3,4
{
Console.WriteLine(item);
}
示例: int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var q = numbers.SkipWhile(i => i % 3 != 0)
.TakeWhile(i => i % 2 != 0);
foreach (var item in q)
{
Console.WriteLine(item);
}
7) . 集合类查询方法
Distinct 去掉集合中的重复项
示例: int[] factorsOf300 = { 2, 2, 3, 5, 5 };
var uniqueFactors = factorsOf300.Distinct(); 输出2,3,5
8) . 生成类查询方法
Range 生成一个整数序列
Repeat 生成一个重复项的序列
示例:var numbers =Enumerable.Range(1, 10);
foreach (var item in numbers)
{ 生成1-10的数字
Console.WriteLine(item);
}
示例:var numbers =Enumerable.Repeat(“Beijing 2008”, 10);
foreach (var item in numbers)
{ 生成10个” Beijing 2008”
Console.WriteLine(item);
}
使用生成类查询方法时,需要注意以下几点:
和其他几类方法不同,Range/Repeat 不是扩展方法,而是普通的静态方法
Range 只能产生整数序列
Repeat 可以产生泛型序列
所有的查询方法都存放在 System.Linq.Enumerable 静态类中
9) . Cast<T>方法
如果数据集合是ArrayList类型的怎么办?ArrayList只是实现了IEnumerable接口,并没有实现IEnumerable<TSource>这个泛型接口,那么,就无法使用IEnumerable<TSource>的扩展方法了,这个时候,可以使用Cast<T>()方法进行转换;
示例: ArrayList posts=new ArrayList{
new post{id=1,attach=“a.txt”},
new post(id=2,attach=“b.xsl”),
new post(id=3,attach=“c.pdf”)}
var dataSource = from post in posts.Cast<Post>()
where post.UserName == userName
select post.Title;
Cast<T>方法如果遇到元素是null,则可能抛出异常或返回null,可以采用OfType<T>()方法,这样会过滤掉null元素;
示例:ArrayList posts=new ArrayList{
new post{id=1,attach=“a.txt”},
new post(id=2,attach=“b.xsl”),
new post(id=3,attach=“c.pdf”)}
var dataSource = from post in posts.OfType<Post>()
where post.UserName == userName
select post.Title;
1.查询分为以下三步:获取数据源、定义查询、执行查询;
2.定义查询后,查询直到需要枚举结果时才被真正执行,这种方式称为“延迟执行(deferred execution)”;
3.当查询方法返回单一值时,查询立即执行;
因此,可以通过以下技巧在定义查询时就强制执行查询
var even = numbers
.Where(p => p % 2 == 0)
.Select(p =>
{
Console.WriteLine("Hi! " + p.ToString());
return p;
}).Count();
2)。 LINQ查询存在以下两种形式
1. Method Syntax, 查询方法方式
主要利用 System.Linq.Enumerable 类中定义的扩展方法和 Lambda 表达式方式进行查询
2. Query Syntax, 查询语句方式
一种更接近 SQL 语法的查询方式
可读性更好
//查询语句
int[] numbers = new int[] { 6, 4, 3, 2, 9, 1, 7, 8, 5 };
var even = from number in numbers
where number % 2 == 0
orderby number descending
select number;
//查询方法
int[] numbers = new int[] { 6, 4, 3, 2, 9, 1, 7, 8, 5 };
var even = numbers
.Where(p => p % 2 == 0)
.OrderByDescending(p => p)
.Select(p => p);
两者的执行效果完全一样;
3)。 查询语句vs查询方法
查询语句与查询方法存在着紧密的关系
CLR本身并不理解查询语句,它只理解查询方法
编译器负责在编译时将查询语句翻译为查询方法
大部分查询方法都有对应的查询语句形式:如 Select() 对应 select 、 OrderBy() 对应 orderby
部分查询方法目前在C#中还没有对应的查询语句:如 Count()和Max() 这时只能采用以下替代方案
查询方法
查询语句 + 查询方法的混合方式;
一般情况下,建议使用可读性更好的查询语句
高级查询方法:
聚合类:
Count,Max/Min,Average
排序类:
ThenBy
分区类:
Take,TakeWhile,Skip,SkipWhile
集合类:
Distinct
生成类:
Range, Repeat
4)。聚合类查询方法
Count 返回集合项的数目
Max/Min 返回集合中的最大值/最小值
Average 返回集合的平均值
Sum 返回集合的总和
示例:int count = (from p in foxRiver8
where p.Age <= 30
select p).Count(); (其他情况类似)
5) . 排序类查询方法
ThenBy 提供复合排序条件
注意:ThenBy查询方法属于查询方法语句所有;查询语句使用orderby排序;
//查询方法
示例:var q = foxRiver8
.OrderBy(p => p.FirstName)
.ThenBy(p => p.LasName)
.ThenBy(p => p.Age);
//查询语句
示例: var q = from p in foxRiver8
orderby p.FirstName, p.LasName, p.Age
select p;
6) . 分区类查询方法
Take 提取指定数量的项
Skip 跳过指定数量的项并获取剩余的项
TakeWhile 根据指定条件提取项
SkipWhile 根据指定条件跳过项
示例:int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var q = numbers.Skip(1).Take(3);
foreach (var item in q) 跳过前1条记录,连续提取3条记录,得到2,3,4
{
Console.WriteLine(item);
}
示例: int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var q = numbers.SkipWhile(i => i % 3 != 0)
.TakeWhile(i => i % 2 != 0);
foreach (var item in q)
{
Console.WriteLine(item);
}
7) . 集合类查询方法
Distinct 去掉集合中的重复项
示例: int[] factorsOf300 = { 2, 2, 3, 5, 5 };
var uniqueFactors = factorsOf300.Distinct(); 输出2,3,5
8) . 生成类查询方法
Range 生成一个整数序列
Repeat 生成一个重复项的序列
示例:var numbers =Enumerable.Range(1, 10);
foreach (var item in numbers)
{ 生成1-10的数字
Console.WriteLine(item);
}
示例:var numbers =Enumerable.Repeat(“Beijing 2008”, 10);
foreach (var item in numbers)
{ 生成10个” Beijing 2008”
Console.WriteLine(item);
}
使用生成类查询方法时,需要注意以下几点:
和其他几类方法不同,Range/Repeat 不是扩展方法,而是普通的静态方法
Range 只能产生整数序列
Repeat 可以产生泛型序列
所有的查询方法都存放在 System.Linq.Enumerable 静态类中
9) . Cast<T>方法
如果数据集合是ArrayList类型的怎么办?ArrayList只是实现了IEnumerable接口,并没有实现IEnumerable<TSource>这个泛型接口,那么,就无法使用IEnumerable<TSource>的扩展方法了,这个时候,可以使用Cast<T>()方法进行转换;
示例: ArrayList posts=new ArrayList{
new post{id=1,attach=“a.txt”},
new post(id=2,attach=“b.xsl”),
new post(id=3,attach=“c.pdf”)}
var dataSource = from post in posts.Cast<Post>()
where post.UserName == userName
select post.Title;
Cast<T>方法如果遇到元素是null,则可能抛出异常或返回null,可以采用OfType<T>()方法,这样会过滤掉null元素;
示例:ArrayList posts=new ArrayList{
new post{id=1,attach=“a.txt”},
new post(id=2,attach=“b.xsl”),
new post(id=3,attach=“c.pdf”)}
var dataSource = from post in posts.OfType<Post>()
where post.UserName == userName
select post.Title;