EntityFramework 7 OrderBy Skip Take-计算排序分页 SQL 翻译
2014-12-03 14:03
681 查看
先解释一下这个标题的意思,OrderBy 在 Linq 语句中,我们经常使用,比如
OrderBy(b => b.BlogId)就是对 BlogId 字段进行升序排序,这是针对一个字段的排序,如果多个字段排序,我们可以使用 ThenBy,或者直接在 OrderBy 中对多个字段进行逗号分割,但有一种场景是,我们要对 OrderBy 增加计算功能,什么意思呢?看一段 SQL 代码:
SELECT [b].[BlogCateId], [b].[BlogId], [b].
异常信息:A query containing the Skip operator must include at least one OrderBy operation.
这段异常信息大概是说使用 Skip 包含至少一个 OrderBy,也就是说我们上面使用orderby b.BlogId * 2 + b.BlogCateId + 34,这段代码并没有起到什么效果,或者说 EF 没有识别出来,总的来说我们这些翻译的 Linq 语句是错误的,但很奇怪的是,我使用 Google 搜索这段异常信息,居然没有搜索到任何的相关信息,难道没有人遇到这个异常?还是我的写法有问题?Skip 是 Linq 分页的关键字,上面报错也是针对 Skip 的,如果我们把 Skip 去掉会怎样呢?
可以看到,我们不使用 Skip,只是使用 Take 进行 Top 查询,是没有任何问题的,还有个问题是,如果使用“计算”性质的 OrderBy,不管是 SQL Server Profiler,还是 EF7 Log 都捕获不到计算的表达式,比如上面的 Take 查询代码,使用 SQL Server Profiler,最后捕获到的 SQL 代码为:
你会看到,居然连 OrderBy 也没有了,不知道是什么原因?前几天也遇到这样类似一个问题:EntityFramework 7 smallint short 奇怪问题(已解决)" target=_blank>
FROM [Blog] AS [b]
ORDER BY ([b].[BlogId] * 2 + [b].[BlogCateId])
OFFSET 0 ROWS FETCH NEXT 100 ROWS ONLY[/code]
这篇博文的主题,其实就是如何用 Linq 翻译这段 SQL 代码,上面这段代码在 SQL Server 中执行没有任何问题,有人说了,很简单啊,比如翻译后的一段代码:[Fact] public void ContextLoad_Test() { using (var context = new BloggingContext()) { var query = from b in context.Blogs orderby b.BlogId * 2 + b.BlogCateId select b; var result = query.Skip(0).Take(100).ToList(); } }
没错,最“直白”的翻译就是这样的,但测试运行后会抛出异常:
异常信息:A query containing the Skip operator must include at least one OrderBy operation.
这段异常信息大概是说使用 Skip 包含至少一个 OrderBy,也就是说我们上面使用orderby b.BlogId * 2 + b.BlogCateId + 34,这段代码并没有起到什么效果,或者说 EF 没有识别出来,总的来说我们这些翻译的 Linq 语句是错误的,但很奇怪的是,我使用 Google 搜索这段异常信息,居然没有搜索到任何的相关信息,难道没有人遇到这个异常?还是我的写法有问题?Skip 是 Linq 分页的关键字,上面报错也是针对 Skip 的,如果我们把 Skip 去掉会怎样呢?
可以看到,我们不使用 Skip,只是使用 Take 进行 Top 查询,是没有任何问题的,还有个问题是,如果使用“计算”性质的 OrderBy,不管是 SQL Server Profiler,还是 EF7 Log 都捕获不到计算的表达式,比如上面的 Take 查询代码,使用 SQL Server Profiler,最后捕获到的 SQL 代码为:
你会看到,居然连 OrderBy 也没有了,不知道是什么原因?前几天也遇到这样类似一个问题:[url=http://www.cnblogs.com/xishuai/p/ef7-smallint-short-where.html]EntityFramework 7 smallint short 奇怪问题(已解决),主要是使用 short where 查询,没有捕获到,最后发现是 Linq 写法问题,应该使用 equals 进行判断,现在发现这两个问题比较相似,郁闷的是,不知道这个 Linq 该如何翻译。
上面这样方式行不通,自己也没有头绪,然后就在 Google 上搜各种关键词,比如:linq orderby math skip,linq calculate math skip 等等,但都尝试了下,还是不行,给出几个参考资料:
[url=http://stackoverflow.com/questions/5741870/custom-order-by-is-it-possible]Custom order by, is it possible?
Linq OrderBy calculation of properties (with join)
LINQ: .NET Language-Integrated Query
网上关于 OrderBy 计算排序的资料,大部分是关于计算排序后获取 Count,然后再进行分组查询出来,比如这段 Linq 代码:var query = from p in yourContext.Activation_Details group p by new { ProductVersion = p.ProductVersion, ProductID = p.ProductID, SubProductID = p.SubProductID } into pgroup let count = pgroup.Count() orderby count select new { Count = count, ProductVersion = pgroup.Key.ProductVersion, ProductID = pgroup.Key.ProductID, SubProductID = pgroup.Key.SubProductID };
但这不是我想要的,花了很多时间也没有找到正确的解决方式,最后换一种思路去思考这个问题,如果 OrderBy 在 Linq 中不能进行计算排序,那就针对这个排序计算进行“翻译”,什么意思呢?比如一开始的ORDER BY ([b].[BlogId] * 2 + B.BlogCateId),其实就是对两个字段进行组合排序,一个是对 BlogId 进行翻倍,然后再加上 BlogCateId 的值,换一种方式其实也是可以的,比如下面这段代码:var result = context.Blogs.OrderBy(b => b.BlogId * 2).ThenBy(b => b.BlogCateId).Skip(0).Take(100).ToList();
执行结果:
不知道这样的写法和一开始上面的 SQL 是不是一样的效果,如果你有更好的“翻译” Linq 代码,还请指教。
相关文章推荐
- SQL order by ID desc/asc加一个排序的字段解决查询慢问题
- LINQ分页和排序,skip和Take 用法
- sql order by 排序多个字段
- SQL ORDER BY(排序)
- LINQ分页和排序,skip和Take 用法
- SQL 分页支持查询 ROW_NUMBER() OVER (ORDER BY ReportID) AS RowNo
- oracle sql 带order by ss desc 进行的分页注意事项
- [SQL基础教程] 3-4 对查询结果进行排序/ORDER BY
- T-SQL查询: TOP N [PERCENT] WITH TIES ORDER BY 顺序排序实例
- 数据库之SQL ORDER BY 语句用于对结果集进行排序
- SQL语句实现根据经纬度计算距离并排序分页
- sql按查询结果第一列排序 (order by+数字)
- 【EntityFramework系列教程三,翻译】在ASP.NET MVC程序中使用EntityFramework对数据进行排序、过滤筛选以及实现分页
- SQL 分页支持查询 ROW_NUMBER() OVER (ORDER BY ReportID) AS RowNo_
- oracle 基础SQL语句 多表查询 子查询 分页查询 合并查询 分组查询 group by having order by
- SQL 分页支持查询 ROW_NUMBER() OVER (ORDER BY ReportID) AS RowNo
- SQL sqlserver order by 1,order by 后面直接加数字,多个字段排序
- SQL中先分组再组内排序再输出的ROW_NUMBER() OVER(partition by..order by..)
- sql order by+字段,指定按照哪个字段来排序
- SQL 分页支持查询 ROW_NUMBER() OVER (ORDER BY ReportID) AS RowNo