前言
才看完一季動漫,完結撒花,末將於禁,原為曹家世代赴湯蹈火!想必看過的都會知道這個,等一下要不吐槽一下翻拍的真人版,○( ^皿^)っHiahia…,好了快醒醒改辦正事兒了,好的,我們接著上一篇文章 http://www.cnblogs.com/DjlNet/p/7220720.html 的問題繼續開始我們今天晚上的解讀!
加戲篇(EF並發)
關於EF中的並發也是開發當中的需要註意的一點,上文中遺漏了這點且感謝園友提醒,這不趕緊來補上,然而博主這裏並不會啪啦啪啦的直接去復制粘貼一坨坨的代碼和文字上來,所以這裏備註一下中英文相關的傳送門即可,望大大們海涵。
關於EF的並發中文的地址(@tkb至簡博文): http://www.cnblogs.com/farb/p/ConcurrencyAndTransctionManagement.html關於文中的前半段則是對並發的理解和在EF中對於並發的表現和解決方案,我這裏就不再贅述了,文中有文字和示例描述問題的產生和解決過程。純屬個人備份記錄而已,知道的園友們,可以直接跳過,O(∩_∩)O哈哈~
其實微軟官方文檔亦有類似文檔,參考地址(英文好的可以直接實用,當然博主看英文略顯吃力,得加油拉凸(艹皿艹 )): https://docs.Microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application ,其中MSDN的的地址: https://msdn.microsoft.com/en-us/library/jj592904(v=vs.113).aspx 該文中含有許多代碼示例可以參考,可以結合當前業務開箱實戰即用。
主角篇
可能下面篇幅略長圖片略多,流量黨慎重,請戰鬥人員帶好護目鏡做好高能預警準備!非戰鬥人員請盡快撤離,好中二....o(≧v≦)o~~
6、EF對復雜的查詢表達式解析能力如何?
這裏有三點的說明一下:1、使用數據庫限定為Sql Server 2012及其以上,其他可能略微有些差異看各自的數據庫驅動中的實現及其對 ExpressionTree樹 是如何解析了的 2、僅限定於查詢語句的解析其中可能包含LINQ基本方法翻譯SQL的對照參考關系 3、特別指出當前是沒有導航屬性的情況,也就是沒有正真的外鍵,這裏可能有人有疑問,為何?基於現實特殊情況而言,對於數據來說插入數據很頻繁且對外鍵的數據檢查不是很強烈,把外鍵的邏輯控制交給應用程序也是一種提高數據庫性能的做法,當然應用層要做好外鍵關系,註意:並不是表達外鍵無用之意,這裏就不贅述其作用了。
前奏: 相信大家部分些許人覺得EF有時候總是給人略顯神秘的感覺,時常再想與自己手寫的SQ相差多遠,到底它能夠翻譯的極致與其中比繞的坑程度在哪裏?對於大多數時候亦能夠比較準確的翻譯為標準SQL,當然我們自然會註意到當查詢邏輯略顯復雜的時候,通常情況下我們自然而然會選擇【查詢表達式】當然混用也是可以的對於運行時來說都是一致的,當然並沒有對lambda喜歡運用做查詢的有敵意哈,其實簡單的查詢lambda更方便或者拼接where條件的時候賊好使,誰用誰知道。還有,關於 linq 的查詢表達式關鍵字會盡數通過編譯器翻譯為lambda表達式和linq的擴展方法調用,所以在CLR代碼運行層面,查詢表達式是透明,所以查詢表達式可以看做是IDE和C#給我們直觀寫代碼的展示方便拉。
這裏為了展示出稍微復雜的查詢,復雜的查詢可能包含一下操作:(內外)連接查詢、分組、聚合、排序、分頁、Case when、DbFuncations、SqlFunctions、數據庫字符串處理函數調用(like..etc)、In查詢、Exists判斷、Distinct去重.....等等,這裏先YY一個數據庫database,及其當中的Tables,然後填充一些數據,當然這裏會展示出表的數據之間的大致關系這樣,在寫出代碼示例時候能確保實驗的真實和可靠性。如下圖所示(請不在意數據庫表設計細節,那不是重點(/≧▽≦)/):
預熱: 首先這裏我們先回顧一下關於LINQ當中一些基本方法的翻譯SQL,雖然有些我們都已經熟知,但是這裏我還是得啰嗦一下,能夠大致羅列出來一個基本對照表,其實一直想做一個對照表,原先的LINQ TO SQL講道理有點老了。
LINQ 方法調用 T-SQL 翻譯與解析 FirstOrDefault / First Top 1 SingleOrDefault / Single Top 2 特別說明:因為Single需要檢測多個元素 Average AVG 特別說明:ef在執行是用了嵌套子查詢的方式,不過在實際執行計劃看來沒有差異,如下圖:






g.Where(x => x.Title.StartsWith("A")).Sum(x => x.Amount) * 2
,相信原因你猜到了,如圖異常顯示如下:


Count(xxx)<=0
換成g.Any(x=>x.Title.StartsWith("A"))
即可,SQL語句稍顯復雜翻譯Count(xx)<=0
,圖中紅框可以輔助觀看:
var temp = db.Rewards.Where(x => x.Amount >= 50).Select(x => new { x.RewarAccountId, x.Amount }).Distinct();
註意: 這裏temp對象是IQueryable對象表示還可以繼續拼接查詢,其中翻譯的SQL如下圖:



var temp = db.Rewards.All(x => x.Amount >= 95);
,翻譯的SQL如下圖【這個沒什麽好說的,比較這個ALL比較少用到至於翻譯SQL,只能╮(╯▽╰)╭】: 
var temp2 = db.Rewards.Any(x => x.Amount >= 95);
,SQL代碼圖如下:
var contains = db.Rewards.Where(x => postidsGuids.Contains(x.PostId));
,無疑會生成 SQL: In 查詢->>> 
var any = db.Rewards.Where(x => postidsGuids.Any(y => y == x.PostId));
,查詢結果與上面一致實驗結果已經證明,那麽問題來了,where中的any生成了什麽代碼,以及兩種寫法的在SQL執行計劃中的百分比(這裏說的一般情況並非絕對,例如:添加索引等操作)?答:直接看圖首先是SQL語句的差別-->> 

OFFSET (pageNum-1)*pageSize ROWS FETCH NEXT pageSize ROWS ONLY
,語法簡單易懂很類似 mysql的 limit 有木有,LINQ代碼->>>> var query = db.Rewards.Where(x => x.Amount >= 50).OrderBy(x => x.Amount).Skip((pageNum - 1) * pageSize).Take(pageSize);
,SQL完全翻譯如下:
system.Data.Entity.SqlServer.SqlFunctions
,這樣就是進行以為更加細膩的操作,類似: var q=EFContext.Products.Where(x=>SqlFunctions.PatIndex("%CD%BLUE%", x.ProductName) > 0);
,當然這裏通過命名空間也得知這是Sql server 才能使用的函數集,因為它不是統一標準的API函數,來吧比卡丘傳送門(關於這玩意的詳細信息):--->>> https://msdn.microsoft.com/en-us/library/system.data.objects.sqlclient.sqlfunctions(v=vs.110).aspx
LINQ時間日期處理
直接參考DbFuncations
微軟官方文檔使用教程即可,多說一句,能在C#處理就不要用數據庫處理了,除外就是這玩意兒來數據庫時間日期把,國際慣例,關於它詳情使用傳送門:https://msdn.microsoft.com/en-us/library/system.data.entity.dbfunctions(v=vs.113).aspx
沸騰: 看到這裏的同學,肯定再想說,好呀,復雜查詢,哼!MD哥TM完全看不出來復雜查詢在哪裏,好的,下面我們就來模擬真實需求做一些復雜查詢看看,從LINQ角度出發或者SQL角度出發,各自的情況到底如何,同樣在我看來SQL與LINQ本來就是不分家的,有些同學何必糾結了非要到底用哪一種這種情緒,當能夠應對80%的需求的時候,用LINQ快速開發和方便調試以及維護等等甚好,當然還有20%定制化需求用SQL也無可厚非,當然這20%是什麽需求,類似CTE等等...那就不得而知了,以上的80%,20%盡數博主自己瞎猜測,切莫當真哦,有些同學可能在擔心哎呀,數據字段變化快業務代碼深陷.....這個其實EF也有全自動化遷移解決方案,EF也能執行Proc但是這個都已經脫離EF本身的意義了,停!扯遠了,好的,下面嘗試復雜查詢邏輯,LINQ魔幻主義開始了。
需求:現在需要統計 在7月份,整個網站中的某些博主身上的所有文章的收益情況報表,具體表頭參考--->>>> 【博主ID 博主名字 總文章數 等待數量 提審數量 駁回數量 發布數量 刪除數量 總評論數量 總的收益】,排序按照文章總數倒敘,然後博客主名字正序,其中分頁情況--->>> int pageSize = 10;int pageNum = 2;
,其中這裏相對於上面的數據庫表,在Post
表增加了如下字段:
public DateTime CreatedTime { get; set; }
public PostStatus PostStatus { get; set; }
public DateTime? PublishTime { get; set; }
其中新增一個枚舉類表示文章的狀態,代碼圖如下圖:
public enum PostStatus
{
Create = 0,
Wait = 1,
Arraigned = 2,
Rejected = 3,
Published = 4,
Removed = 5
}
代碼編寫:代碼段中有註釋,可方便理解,如果有什麽其他LINQ方案或者有什麽不對的地方,可以在評論區回復我哦,還有如果是你手寫SQL語句的話,該怎麽寫呢,怎麽寫相對來說容易理解以及執行計劃更優呢,我會認真看各位園友的評論或者問題的,O(∩_∩)O嗯!
private static void TestLinqToSqlComplex()
{
// 需求1、現在需要統計 在7月份,整個網站中的某些博主身上的所有文章的收益情況報表
var db = new DemoDbContext();
DateTime startDateTime = new DateTime(2017, 7, 1);
DateTime endDateTime = new DateTime(2017, 7, 31, 23, 59, 59);
// 博主ID 博主名字 總文章數 等待數量 提審數量 駁回數量 發布數量 刪除數量 總評論數量 總的收益
// 其他:按照數量倒序排序+分頁
// 0、定義 每頁數量和查看第幾頁
int pageSize = 10;
int pageNum = 2;
// 1、緩存臨時文章變量
var posts = db.Posts.Where(x => x.CreatedTime >= startDateTime && x.CreatedTime <= endDateTime);
//var temp1 = posts.ToList();
// 2、緩存文章與評論的數據變量
var postCommentsQueryable = from post in posts
join comment in db.Comments on post.PostId equals comment.PostId into leftJoined
from coment1 in leftJoined.DefaultIfEmpty()
group coment1 by new { post.BlogId, post.PostId, post.PostStatus } into grouped
select new
{
grouped.Key.BlogId,
grouped.Key.PostId,
grouped.Key.PostStatus,
TotalCommentQty = grouped.Count()
};
//var temp2 = postCommentsQueryable.ToList();
// 3、緩存文章與打賞的數據變量
var postRewardsQueryable = from post in posts
join reward in db.Rewards on post.PostId equals reward.PostId into leftJoined
from reward1 in leftJoined.DefaultIfEmpty()
group reward1 by new { post.BlogId, post.PostId, post.PostStatus } into grouped
select new
{
grouped.Key.BlogId,
grouped.Key.PostId,
grouped.Key.PostStatus,
TotalRewardAmount = grouped.Any(x => x.Amount > 0) ? grouped.Sum(x => x.Amount) : 0
};
//var temp3 = postRewardsQueryable.ToList();
// 4、合並數據
var tempQueryable = from x in postCommentsQueryable
join y in postRewardsQueryable on new { x.BlogId, x.PostId, x.PostStatus } equals new
{
y.BlogId,
y.PostId,
y.PostStatus
}
select new
{
x.BlogId,
x.PostId,
x.PostStatus,
x.TotalCommentQty,
y.TotalRewardAmount
};
//var temp4 = tempQueryable.ToList();
// 5、數據歸並匯總
var query = from blog in db.Blogs
join post in tempQueryable on blog.BlogId equals post.BlogId into leftJoined
from post1 in leftJoined.DefaultIfEmpty()
group post1 by new { blog.BlogId, blog.AuthorName } into grouped
select new
{
grouped.Key.BlogId,
grouped.Key.AuthorName,
TotalPostQty = grouped.Count(),
TotalWaitPostQty = grouped.Count(x => x.PostStatus == PostStatus.Wait),
TotalArraignedPostQty = grouped.Count(x => x.PostStatus == PostStatus.Arraigned),
TotalRejectedPostQty = grouped.Count(x => x.PostStatus == PostStatus.Rejected),
TotalPublishedPostQty = grouped.Count(x => x.PostStatus == PostStatus.Published),
TotalRemovedPostQty = grouped.Count(x => x.PostStatus == PostStatus.Removed),
TotalCommemtQty = grouped.Sum(x => x.TotalCommentQty),
TotalRewardAmount = grouped.Sum(x => x.TotalRewardAmount)
};
//var temp5 = query.ToList();
// 6、排序分頁
var result = query.OrderByDescending(x => x.TotalPostQty).ThenBy(x => x.AuthorName).Skip((pageNum - 1) * pageSize).Take(pageSize);
var temp6 = result.ToList();
Console.WriteLine(@"博主ID 博主名字 總文章數 等待數量 提審數量 駁回數量 發布數量 刪除數量 總評論數量 總的收益");
temp6.ForEach(x =>
{
Console.WriteLine($@"{x.BlogId} {x.AuthorName} {x.TotalPostQty} {x.TotalWaitPostQty} {x.TotalArraignedPostQty} {x.TotalRejectedPostQty} {x.TotalPublishedPostQty} {x.TotalRemovedPostQty} {x.TotalCommemtQty} {x.TotalRewardAmount}");
});
Console.WriteLine(result.ToString());
}
SQL翻譯成果與查詢結果:【上圖】---->>>:
由於這裏的SQL語句太TM長了,這裏貼圖帖不了直接復制SQL出來貼上來把,想必大家也不想看,哈哈---->>>>>:
SELECT
[Project27].[C4] AS [C1],
[Project27].[BlogId] AS [BlogId],
[Project27].[AuthorName] AS [AuthorName],
[Project27].[C1] AS [C2],
[Project27].[C5] AS [C3],
[Project27].[C6] AS [C4],
[Project27].[C7] AS [C5],
[Project27].[C8] AS [C6],
[Project27].[C9] AS [C7],
[Project27].[C2] AS [C8],
[Project27].[C3] AS [C9]
FROM ( SELECT
[Project26].[C1] AS [C1],
[Project26].[C2] AS [C2],
[Project26].[C3] AS [C3],
[Project26].[BlogId] AS [BlogId],
[Project26].[AuthorName] AS [AuthorName],
1 AS [C4],
[Project26].[C4] AS [C5],
[Project26].[C5] AS [C6],
[Project26].[C6] AS [C7],
[Project26].[C7] AS [C8],
[Project26].[C8] AS [C9]
FROM ( SELECT
[Project22].[C1] AS [C1],
[Project22].[C2] AS [C2],
[Project22].[C3] AS [C3],
[Project22].[BlogId] AS [BlogId],
[Project22].[AuthorName] AS [AuthorName],
[Project22].[C4] AS [C4],
[Project22].[C5] AS [C5],
[Project22].[C6] AS [C6],
[Project22].[C7] AS [C7],
(SELECT
COUNT(1) AS [A1]
FROM ( SELECT
@p__linq__0 AS [p__linq__0],
@p__linq__1 AS [p__linq__1],
@p__linq__2 AS [p__linq__2],
@p__linq__3 AS [p__linq__3],
[Extent28].[BlogId] AS [BlogId],
[Extent28].[AuthorName] AS [AuthorName],
[Join24].[PostId1] AS [PostId],
[Join24].[BlogId1] AS [BlogId1],
[Join24].[PostStatus1] AS [PostStatus],
[Join24].[PostId2] AS [PostId1],
[Join24].[BlogId2] AS [BlogId2],
[Join24].[PostStatus2] AS [PostStatus1]
FROM [dbo].[Blog] AS [Extent28]
LEFT OUTER JOIN (SELECT [Distinct9].[PostId] AS [PostId1], [Distinct9].[BlogId] AS [BlogId1], [Distinct9].[PostStatus] AS [PostStatus1], [Distinct10].[PostId] AS [PostId2], [Distinct10].[BlogId] AS [BlogId2], [Distinct10].[PostStatus] AS [PostStatus2]
FROM (SELECT DISTINCT
[Extent29].[PostId] AS [PostId],
[Extent29].[BlogId] AS [BlogId],
[Extent29].[PostStatus] AS [PostStatus]
FROM [dbo].[Post] AS [Extent29]
LEFT OUTER JOIN [dbo].[Comment] AS [Extent30] ON [Extent29].[PostId] = [Extent30].[PostId]
WHERE ([Extent29].[CreatedTime] >= @p__linq__0) AND ([Extent29].[CreatedTime] <= @p__linq__1) ) AS [Distinct9]
INNER JOIN (SELECT DISTINCT
[Extent31].[PostId] AS [PostId],
[Extent31].[BlogId] AS [BlogId],
[Extent31].[PostStatus] AS [PostStatus]
FROM [dbo].[Post] AS [Extent31]
LEFT OUTER JOIN [dbo].[Reward] AS [Extent32] ON [Extent31].[PostId] = [Extent32].[PostId]
WHERE ([Extent31].[CreatedTime] >= @p__linq__2) AND ([Extent31].[CreatedTime] <= @p__linq__3) ) AS [Distinct10] ON ([Distinct9].[BlogId] = [Distinct10].[BlogId]) AND ([Distinct9].[PostId] = [Distinct10].[PostId]) AND ([Distinct9].[PostStatus] = [Distinct10].[PostStatus]) ) AS [Join24] ON [Extent28].[BlogId] = [Join24].[BlogId1]
WHERE ([Project22].[BlogId] = [Extent28].[BlogId]) AND (([Project22].[AuthorName] = [Extent28].[AuthorName]) OR (([Project22].[AuthorName] IS NULL) AND ([Extent28].[AuthorName] IS NULL))) AND (5 = [Join24].[PostStatus1])
) AS [Project25]) AS [C8]
FROM ( SELECT
[Project18].[C1] AS [C1],
[Project18].[C2] AS [C2],
[Project18].[C3] AS [C3],
[Project18].[BlogId] AS [BlogId],
[Project18].[AuthorName] AS [AuthorName],
[Project18].[C4] AS [C4],
[Project18].[C5] AS [C5],
[Project18].[C6] AS [C6],
(SELECT
COUNT(1) AS [A1]
FROM ( SELECT
@p__linq__0 AS [p__linq__0],
@p__linq__1 AS [p__linq__1],
@p__linq__2 AS [p__linq__2],
@p__linq__3 AS [p__linq__3],
[Extent23].[BlogId] AS [BlogId],
[Extent23].[AuthorName] AS [AuthorName],
[Join20].[PostId3] AS [PostId],
[Join20].[BlogId3] AS [BlogId1],
[Join20].[PostStatus3] AS [PostStatus],
[Join20].[PostId4] AS [PostId1],
[Join20].[BlogId4] AS [BlogId2],
[Join20].[PostStatus4] AS [PostStatus1]
FROM [dbo].[Blog] AS [Extent23]
LEFT OUTER JOIN (SELECT [Distinct7].[PostId] AS [PostId3], [Distinct7].[BlogId] AS [BlogId3], [Distinct7].[PostStatus] AS [PostStatus3], [Distinct8].[PostId] AS [PostId4], [Distinct8].[BlogId] AS [BlogId4], [Distinct8].[PostStatus] AS [PostStatus4]
FROM (SELECT DISTINCT
[Extent24].[PostId] AS [PostId],
[Extent24].[BlogId] AS [BlogId],
[Extent24].[PostStatus] AS [PostStatus]
FROM [dbo].[Post] AS [Extent24]
LEFT OUTER JOIN [dbo].[Comment] AS [Extent25] ON [Extent24].[PostId] = [Extent25].[PostId]
WHERE ([Extent24].[CreatedTime] >= @p__linq__0) AND ([Extent24].[CreatedTime] <= @p__linq__1) ) AS [Distinct7]
INNER JOIN (SELECT DISTINCT
[Extent26].[PostId] AS [PostId],
[Extent26].[BlogId] AS [BlogId],
[Extent26].[PostStatus] AS [PostStatus]
FROM [dbo].[Post] AS [Extent26]
LEFT OUTER JOIN [dbo].[Reward] AS [Extent27] ON [Extent26].[PostId] = [Extent27].[PostId]
WHERE ([Extent26].[CreatedTime] >= @p__linq__2) AND ([Extent26].[CreatedTime] <= @p__linq__3) ) AS [Distinct8] ON ([Distinct7].[BlogId] = [Distinct8].[BlogId]) AND ([Distinct7].[PostId] = [Distinct8].[PostId]) AND ([Distinct7].[PostStatus] = [Distinct8].[PostStatus]) ) AS [Join20] ON [Extent23].[BlogId] = [Join20].[BlogId3]
WHERE ([Project18].[BlogId] = [Extent23].[BlogId]) AND (([Project18].[AuthorName] = [Extent23].[AuthorName]) OR (([Project18].[AuthorName] IS NULL) AND ([Extent23].[AuthorName] IS NULL))) AND (4 = [Join20].[PostStatus3])
) AS [Project21]) AS [C7]
FROM ( SELECT
[Project14].[C1] AS [C1],
[Project14].[C2] AS [C2],
[Project14].[C3] AS [C3],
[Project14].[BlogId] AS [BlogId],
[Project14].[AuthorName] AS [AuthorName],
[Project14].[C4] AS [C4],
[Project14].[C5] AS [C5],
(SELECT
COUNT(1) AS [A1]
FROM ( SELECT
@p__linq__0 AS [p__linq__0],
@p__linq__1 AS [p__linq__1],
@p__linq__2 AS [p__linq__2],
@p__linq__3 AS [p__linq__3],
[Extent18].[BlogId] AS [BlogId],
[Extent18].[AuthorName] AS [AuthorName],
[Join16].[PostId5] AS [PostId],
[Join16].[BlogId5] AS [BlogId1],
[Join16].[PostStatus5] AS [PostStatus],
[Join16].[PostId6] AS [PostId1],
[Join16].[BlogId6] AS [BlogId2],
[Join16].[PostStatus6] AS [PostStatus1]
FROM [dbo].[Blog] AS [Extent18]
LEFT OUTER JOIN (SELECT [Distinct5].[PostId] AS [PostId5], [Distinct5].[BlogId] AS [BlogId5], [Distinct5].[PostStatus] AS [PostStatus5], [Distinct6].[PostId] AS [PostId6], [Distinct6].[BlogId] AS [BlogId6], [Distinct6].[PostStatus] AS [PostStatus6]
FROM (SELECT DISTINCT
[Extent19].[PostId] AS [PostId],
[Extent19].[BlogId] AS [BlogId],
[Extent19].[PostStatus] AS [PostStatus]
FROM [dbo].[Post] AS [Extent19]
LEFT OUTER JOIN [dbo].[Comment] AS [Extent20] ON [Extent19].[PostId] = [Extent20].[PostId]
WHERE ([Extent19].[CreatedTime] >= @p__linq__0) AND ([Extent19].[CreatedTime] <= @p__linq__1) ) AS [Distinct5]
INNER JOIN (SELECT DISTINCT
[Extent21].[PostId] AS [PostId],
[Extent21].[BlogId] AS [BlogId],
[Extent21].[PostStatus] AS [PostStatus]
FROM [dbo].[Post] AS [Extent21]
LEFT OUTER JOIN [dbo].[Reward] AS [Extent22] ON [Extent21].[PostId] = [Extent22].[PostId]
WHERE ([Extent21].[CreatedTime] >= @p__linq__2) AND ([Extent21].[CreatedTime] <= @p__linq__3) ) AS [Distinct6] ON ([Distinct5].[BlogId] = [Distinct6].[BlogId]) AND ([Distinct5].[PostId] = [Distinct6].[PostId]) AND ([Distinct5].[PostStatus] = [Distinct6].[PostStatus]) ) AS [Join16] ON [Extent18].[BlogId] = [Join16].[BlogId5]
WHERE ([Project14].[BlogId] = [Extent18].[BlogId]) AND (([Project14].[AuthorName] = [Extent18].[AuthorName]) OR (([Project14].[AuthorName] IS NULL) AND ([Extent18].[AuthorName] IS NULL))) AND (3 = [Join16].[PostStatus5])
) AS [Project17]) AS [C6]
FROM ( SELECT
[Project10].[C1] AS [C1],
[Project10].[C2] AS [C2],
[Project10].[C3] AS [C3],
[Project10].[BlogId] AS [BlogId],
[Project10].[AuthorName] AS [AuthorName],
[Project10].[C4] AS [C4],
(SELECT
COUNT(1) AS [A1]
FROM ( SELECT
@p__linq__0 AS [p__linq__0],
@p__linq__1 AS [p__linq__1],
@p__linq__2 AS [p__linq__2],
@p__linq__3 AS [p__linq__3],
[Extent13].[BlogId] AS [BlogId],
[Extent13].[AuthorName] AS [AuthorName],
[Join12].[PostId7] AS [PostId],
[Join12].[BlogId7] AS [BlogId1],
[Join12].[PostStatus7] AS [PostStatus],
[Join12].[PostId8] AS [PostId1],
[Join12].[BlogId8] AS [BlogId2],
[Join12].[PostStatus8] AS [PostStatus1]
FROM [dbo].[Blog] AS [Extent13]
LEFT OUTER JOIN (SELECT [Distinct3].[PostId] AS [PostId7], [Distinct3].[BlogId] AS [BlogId7], [Distinct3].[PostStatus] AS [PostStatus7], [Distinct4].[PostId] AS [PostId8], [Distinct4].[BlogId] AS [BlogId8], [Distinct4].[PostStatus] AS [PostStatus8]
FROM (SELECT DISTINCT
[Extent14].[PostId] AS [PostId],
[Extent14].[BlogId] AS [BlogId],
[Extent14].[PostStatus] AS [PostStatus]
FROM [dbo].[Post] AS [Extent14]
LEFT OUTER JOIN [dbo].[Comment] AS [Extent15] ON [Extent14].[PostId] = [Extent15].[PostId]
WHERE ([Extent14].[CreatedTime] >= @p__linq__0) AND ([Extent14].[CreatedTime] <= @p__linq__1) ) AS [Distinct3]
INNER JOIN (SELECT DISTINCT
[Extent16].[PostId] AS [PostId],
[Extent16].[BlogId] AS [BlogId],
[Extent16].[PostStatus] AS [PostStatus]
FROM [dbo].[Post] AS [Extent16]
LEFT OUTER JOIN [dbo].[Reward] AS [Extent17] ON [Extent16].[PostId] = [Extent17].[PostId]
WHERE ([Extent16].[CreatedTime] >= @p__linq__2) AND ([Extent16].[CreatedTime] <= @p__linq__3) ) AS [Distinct4] ON ([Distinct3].[BlogId] = [Distinct4].[BlogId]) AND ([Distinct3].[PostId] = [Distinct4].[PostId]) AND ([Distinct3].[PostStatus] = [Distinct4].[PostStatus]) ) AS [Join12] ON [Extent13].[BlogId] = [Join12].[BlogId7]
WHERE ([Project10].[BlogId] = [Extent13].[BlogId]) AND (([Project10].[AuthorName] = [Extent13].[AuthorName]) OR (([Project10].[AuthorName] IS NULL) AND ([Extent13].[AuthorName] IS NULL))) AND (2 = [Join12].[PostStatus7])
) AS [Project13]) AS [C5]
FROM ( SELECT
[Project6].[C1] AS [C1],
[Project6].[C2] AS [C2],
[Project6].[C3] AS [C3],
[Project6].[BlogId] AS [BlogId],
[Project6].[AuthorName] AS [AuthorName],
(SELECT
COUNT(1) AS [A1]
FROM ( SELECT
@p__linq__0 AS [p__linq__0],
@p__linq__1 AS [p__linq__1],
@p__linq__2 AS [p__linq__2],
@p__linq__3 AS [p__linq__3],
[Extent8].[BlogId] AS [BlogId],
[Extent8].[AuthorName] AS [AuthorName],
[Join8].[PostId9] AS [PostId],
[Join8].[BlogId9] AS [BlogId1],
[Join8].[PostStatus9] AS [PostStatus],
[Join8].[PostId10] AS [PostId1],
[Join8].[BlogId10] AS [BlogId2],
[Join8].[PostStatus10] AS [PostStatus1]
FROM [dbo].[Blog] AS [Extent8]
LEFT OUTER JOIN (SELECT [Distinct1].[PostId] AS [PostId9], [Distinct1].[BlogId] AS [BlogId9], [Distinct1].[PostStatus] AS [PostStatus9], [Distinct2].[PostId] AS [PostId10], [Distinct2].[BlogId] AS [BlogId10], [Distinct2].[PostStatus] AS [PostStatus10]
FROM (SELECT DISTINCT
[Extent9].[PostId] AS [PostId],
[Extent9].[BlogId] AS [BlogId],
[Extent9].[PostStatus] AS [PostStatus]
FROM [dbo].[Post] AS [Extent9]
LEFT OUTER JOIN [dbo].[Comment] AS [Extent10] ON [Extent9].[PostId] = [Extent10].[PostId]
WHERE ([Extent9].[CreatedTime] >= @p__linq__0) AND ([Extent9].[CreatedTime] <= @p__linq__1) ) AS [Distinct1]
INNER JOIN (SELECT DISTINCT
[Extent11].[PostId] AS [PostId],
[Extent11].[BlogId] AS [BlogId],
[Extent11].[PostStatus] AS [PostStatus]
FROM [dbo].[Post] AS [Extent11]
LEFT OUTER JOIN [dbo].[Reward] AS [Extent12] ON [Extent11].[PostId] = [Extent12].[PostId]
WHERE ([Extent11].[CreatedTime] >= @p__linq__2) AND ([Extent11].[CreatedTime] <= @p__linq__3) ) AS [Distinct2] ON ([Distinct1].[BlogId] = [Distinct2].[BlogId]) AND ([Distinct1].[PostId] = [Distinct2].[PostId]) AND ([Distinct1].[PostStatus] = [Distinct2].[PostStatus]) ) AS [Join8] ON [Extent8].[BlogId] = [Join8].[BlogId9]
WHERE ([Project6].[BlogId] = [Extent8].[BlogId]) AND (([Project6].[AuthorName] = [Extent8].[AuthorName]) OR (([Project6].[AuthorName] IS NULL) AND ([Extent8].[AuthorName] IS NULL))) AND (1 = [Join8].[PostStatus9])
) AS [Project9]) AS [C4]
FROM ( SELECT
[GroupBy3].[A1] AS [C1],
[GroupBy3].[A2] AS [C2],
[GroupBy3].[A3] AS [C3],
[GroupBy3].[K1] AS [BlogId],
[GroupBy3].[K2] AS [AuthorName]
FROM ( SELECT
[Project5].[BlogId] AS [K1],
[Project5].[AuthorName] AS [K2],
COUNT(1) AS [A1],
SUM([Project5].[C1]) AS [A2],
SUM([Project5].[C2]) AS [A3]
FROM ( SELECT
@p__linq__0 AS [p__linq__0],
@p__linq__1 AS [p__linq__1],
@p__linq__2 AS [p__linq__2],
@p__linq__3 AS [p__linq__3],
[Extent1].[BlogId] AS [BlogId],
[Extent1].[AuthorName] AS [AuthorName],
[Join4].[PostId11] AS [PostId],
[Join4].[BlogId11] AS [BlogId1],
[Join4].[PostStatus11] AS [PostStatus],
[Join4].[C11] AS [C1],
[Join4].[PostId12] AS [PostId1],
[Join4].[BlogId12] AS [BlogId2],
[Join4].[PostStatus12] AS [PostStatus1],
[Join4].[C12] AS [C2]
FROM [dbo].[Blog] AS [Extent1]
LEFT OUTER JOIN (SELECT [Project1].[PostId] AS [PostId11], [Project1].[BlogId] AS [BlogId11], [Project1].[PostStatus] AS [PostStatus11], [Project1].[C1] AS [C11], [Project4].[PostId] AS [PostId12], [Project4].[BlogId] AS [BlogId12], [Project4].[PostStatus] AS [PostStatus12], [Project4].[C1] AS [C12]
FROM (SELECT
[GroupBy1].[K1] AS [PostId],
[GroupBy1].[K2] AS [BlogId],
[GroupBy1].[K3] AS [PostStatus],
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
[Extent2].[PostId] AS [K1],
[Extent2].[BlogId] AS [K2],
[Extent2].[PostStatus] AS [K3],
COUNT(1) AS [A1]
FROM [dbo].[Post] AS [Extent2]
LEFT OUTER JOIN [dbo].[Comment] AS [Extent3] ON [Extent2].[PostId] = [Extent3].[PostId]
WHERE ([Extent2].[CreatedTime] >= @p__linq__0) AND ([Extent2].[CreatedTime] <= @p__linq__1)
GROUP BY [Extent2].[PostId], [Extent2].[BlogId], [Extent2].[PostStatus]
) AS [GroupBy1] ) AS [Project1]
INNER JOIN (SELECT
[Project2].[PostId] AS [PostId],
[Project2].[BlogId] AS [BlogId],
[Project2].[PostStatus] AS [PostStatus],
CASE WHEN ( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[Post] AS [Extent6]
INNER JOIN [dbo].[Reward] AS [Extent7] ON [Extent6].[PostId] = [Extent7].[PostId]
WHERE ([Extent6].[CreatedTime] >= @p__linq__2) AND ([Extent6].[CreatedTime] <= @p__linq__3) AND ([Project2].[BlogId] = [Extent6].[BlogId]) AND ([Project2].[PostId] = [Extent6].[PostId]) AND ([Project2].[PostStatus] = [Extent6].[PostStatus]) AND ([Extent7].[Amount] > cast(0 as decimal(18)))
)) THEN [Project2].[C1] ELSE cast(0 as decimal(18)) END AS [C1]
FROM ( SELECT
[GroupBy2].[K1] AS [PostId],
[GroupBy2].[K2] AS [BlogId],
[GroupBy2].[K3] AS [PostStatus],
[GroupBy2].[A1] AS [C1]
FROM ( SELECT
[Extent4].[PostId] AS [K1],
[Extent4].[BlogId] AS [K2],
[Extent4].[PostStatus] AS [K3],
SUM([Extent5].[Amount]) AS [A1]
FROM [dbo].[Post] AS [Extent4]
LEFT OUTER JOIN [dbo].[Reward] AS [Extent5] ON [Extent4].[PostId] = [Extent5].[PostId]
WHERE ([Extent4].[CreatedTime] >= @p__linq__2) AND ([Extent4].[CreatedTime] <= @p__linq__3)
GROUP BY [Extent4].[PostId], [Extent4].[BlogId], [Extent4].[PostStatus]
) AS [GroupBy2]
) AS [Project2] ) AS [Project4] ON ([Project1].[BlogId] = [Project4].[BlogId]) AND ([Project1].[PostId] = [Project4].[PostId]) AND ([Project1].[PostStatus] = [Project4].[PostStatus]) ) AS [Join4] ON [Extent1].[BlogId] = [Join4].[BlogId11]
) AS [Project5]
GROUP BY [Project5].[BlogId], [Project5].[AuthorName]
) AS [GroupBy3]
) AS [Project6]
) AS [Project10]
) AS [Project14]
) AS [Project18]
) AS [Project22]
) AS [Project26]
) AS [Project27]
ORDER BY [Project27].[C1] DESC, [Project27].[AuthorName] ASC
OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY
總結
至此,相信看到這裏的同學,心中難免波瀾,知道在復雜的情況下EF也是如此鋒利和韌性,就好比那把瑞士軍刀,亦可一刀致命亦可遊刃有余,可以認為博主在這裏打了一波EF廣告,哈哈O(∩_∩)O哈哈~ ,如果覺得博主這一篇小文還可以,就施舍給我一個贊吧!回到我們的題目,EF對與復雜情況的支持度如何的問題,當然不能僅憑我一文亦或者一個DEMO一個例子,就能說明問題,是千千萬萬的EF使用者和 entity framework nuget package 下載量來詮釋這個問題,OK,我們的第六個問題算是通過發現問題、對比問題、思考問題、解析問題、解決問題以及後面的總結,以上便是證明!現在,回到我們上期的問題當中,回顧一下便是:
7、開發者怎麽審查EF翻譯的SQL語句?
8、開發者怎麽監控EF在網站運行情況?
其實當聰明的你也知道,博主在解決問題6的時候已經,發現了兩種方式可以拿到EF的SQL語句,這裏下期在說明吧,哈哈哈,以及問題8關於EF的全面監控和自定義開關來控制SQL的跟蹤和展示問題,這一切都是圍繞了EF構建了一整套的解決方案,ヾ(≧O≦)〃嗷~ !!!!好的,我們下期見!求關註求互粉,(^-^)
後記
夜深了,博主回頭看看,這篇博文原來已經耗時了好幾天晚上的時間了哈,不過呢,把在尋找解決問題的途中當做是一種享受也是一個好的自我安慰拉,近期博主的公司準備去團建拉,雖然只有一天,好吧,該吐槽還是得吐槽哈,在這裏呢,還多說一句,在浩浩蕩蕩的以業務為主的公司當中,泛指各地不止廣州,不止博主自己,有時都是深陷業務代碼不能自拔,一天天在完成基本編碼之後都難以抽身投身於自己想法和實踐當中去,當然這裏並不是誰的錯,這點得明確!那麽問題來了,俗話說得好,時間就像乳溝,擠擠就有了!開個玩笑拉,時間不早了,老鐵們,晚安廣州!!!
Tags: 並發 文中 可以 英文 直接 曹家
文章來源: