EntityFramework 7 OrderBy Skip Take-计算排序分页 SQL 翻译
先解釋一下這個標題的意思,OrderBy 在 Linq 語句中,我們經常使用,比如 OrderBy(b => b.BlogId) 就是對 BlogId 字段進行升序排序,這是針對一個字段的排序,如果多個字段排序,我們可以使用 ThenBy,或者直接在 OrderBy 中對多個字段進行逗號分割,但有一種場景是,我們要對 OrderBy 增加計算功能,什么意思呢?看一段 SQL 代碼:
SELECT [b].[BlogCateId], [b].[BlogId], [b].[Url] FROM [Blog] AS [b] ORDER BY ([b].[BlogId] * 2 + [b].[BlogCateId]) OFFSET 0 ROWS FETCH NEXT 100 ROWS ONLY這篇博文的主題,其實就是如何用 Linq 翻譯這段 SQL 代碼,上面這段代碼在 SQL Server 中執行沒有任何問題,有人說了,很簡單啊,比如翻譯后的一段代碼:
[Fact] public void ContextLoad_Test() {using (var context = new BloggingContext()){var query = from b in context.Blogsorderby b.BlogId * 2 + b.BlogCateIdselect 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 也沒有了,不知道是什么原因?前幾天也遇到這樣類似一個問題:EntityFramework 7 smallint short 奇怪問題(已解決),主要是使用 short where 查詢,沒有捕獲到,最后發現是 Linq 寫法問題,應該使用 equals 進行判斷,現在發現這兩個問題比較相似,郁悶的是,不知道這個 Linq 該如何翻譯。
上面這樣方式行不通,自己也沒有頭緒,然后就在 Google 上搜各種關鍵詞,比如:linq orderby math skip,linq calculate math skip 等等,但都嘗試了下,還是不行,給出幾個參考資料:
- 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_Detailsgroup p by new{ProductVersion = p.ProductVersion,ProductID = p.ProductID,SubProductID = p.SubProductID}into pgrouplet count = pgroup.Count()orderby countselect 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 代碼,還請指教。
轉載于:https://www.cnblogs.com/xishuai/p/ef7-orderby-thenby-skip-take-math.html
總結
以上是生活随笔為你收集整理的EntityFramework 7 OrderBy Skip Take-计算排序分页 SQL 翻译的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 程矢Axure夜话:Axure手机原型视
- 下一篇: could not initialize