走进Linq-Linq to Objects(下)实例篇
[1] 走进Linq-Linq to Objects(下)实例篇
[2] 走进Linq-Linq to Objects(下)实例篇
[3] 走进Linq-Linq to Objects(下)实例篇
[4] 走进Linq-Linq to Objects(下)实例篇
[5] 走进Linq-Linq to Objects(下)实例篇
[6] 走进Linq-Linq to Objects(下)实例篇
[2] 走进Linq-Linq to Objects(下)实例篇
[3] 走进Linq-Linq to Objects(下)实例篇
[4] 走进Linq-Linq to Objects(下)实例篇
[5] 走进Linq-Linq to Objects(下)实例篇
[6] 走进Linq-Linq to Objects(下)实例篇
系列文章导航:
不能不说的C#特性-迭代器(下),yield以及流的延迟计算
走进Linq-Linq to SQL How do I(1)
走进Linq-Linq to SQL How do I(2)
走进Linq-Linq to SQL How do I(3)
走进Linq-Linq to SQL源代码赏析 Table
走进Linq-Linq to SQL源代码赏析之Provider的初始化
走进Linq-Linq to SQL源代码赏析,通过Linq to SQL看Linq
排序
在数据驱动的应用中我们经常需要对数据根据一些属性进行排序,而通常这些排序的属性应该是用户可以自己设置的,比如博客,可以根据点击率排序,也可以根据评论排序,甚至两者都作为排序根据。还有什么顺序啊,倒序啊,也就是这个排序是个动态的。那我们是不是要写一大串if…else…进行判断,然后写不同的Linq表达式:
if(根据点击率排序){
return from post in posts
where post.Title ==”yuyijq”
orderby post.Click
select post;
}else if(…){
…
}
return from post in posts
where post.Title ==”yuyijq”
orderby post.Click
select post;
}else if(…){
…
}
如果是这样也太麻烦了,我们还是来看看OrderBy的方法原型:
OrderedSequence<TElement> OrderBy<TElement, TKey>(
this IEnumerable<TElement> source, Func<TElement, TKey> keySelector)
this IEnumerable<TElement> source, Func<TElement, TKey> keySelector)
实际上OrderBy方法需要的就是一个排序关键字选择的delegate,输入进去一个集合元素,返回一个排序的关键字就ok了,像下面这样:
Func<TElement,TKey> selector = post => post.Click;
return from post in posts
where post.UserName = “yuyijq”
orderby selector(post)
select post;
return from post in posts
where post.UserName = “yuyijq”
orderby selector(post)
select post;
那我们甚至可以封装一个排序的方法:
public IEnumerable<Post> Sort<TKey>(string userName,Func<Post,TKey> selector)
{
return from post in posts
where post.UserName == userName
orderby selector(post)
select post;
}
{
return from post in posts
where post.UserName == userName
orderby selector(post)
select post;
}
用户需要定制的选择是升序排序还是降序排序这个咋整?那弄个条件判断呗:
public IEnumerable<Post> Sort<TKey>(string userName,Func<Post,TKey> selector,bool isAsc)
{
return from post in posts
where post.UserName == userName
isAsc ?Orderby selector(post):orderby selector(post) des
select post;
}
{
return from post in posts
where post.UserName == userName
isAsc ?Orderby selector(post):orderby selector(post) des
select post;
}
可惜的是上面的写法行不通,在查询表达式里这样写是不行的,但我们可以使用方法调用的方式:
public IEnumerable<Post> Sort<TKey>(string userName,Func<Post,TKey> selector,bool isAsc)
{
var newPosts = from post in posts
where post.UserName == userName
select post;
return isAsc ?newPosts.Orderby(selector(post)):newPosts. OrderByDescending(selector(post));
}
{
var newPosts = from post in posts
where post.UserName == userName
select post;
return isAsc ?newPosts.Orderby(selector(post)):newPosts. OrderByDescending(selector(post));
}
你看,灵活的将方法调用和查询表达式组合,我们能应付很多情况。因为查询表达式有它特定的语法约束,所以有的时候并不能非常动态,这个时候我们可以配合方法调用的方式,如此一组合方便多了。那要是我想根据评论数目排序后再根据点击率排序呢?放两个关键字就可以了:
var dataSource = from post in posts
where post.UserName == "yuyijq"
orderby post.Click,post.Comments
select post.Title;
where post.UserName == "yuyijq"
orderby post.Click,post.Comments
select post.Title;
实际上orderby post.Click,post.Comments这里会生成:
posts.OrderBy(post=>post.Click).ThenBy(post=>post.Comments);