DAL層從數據庫中將數據讀出來后,傳遞給BLL層,再通過BLL處理數據后,向WEB層返回,最后到頁面上輸出,這是一個過程,在這個過程中我需要說兩句,BLL層與WEB層通訊肯定是List,IList等等,即實實在在的數據,而DAL層向BLL層返回數據時,就需要注意了,因為DAL層返回一般是完整的結果集,而在BLL層根據具體的業務,再進行字段的過濾,這對於減少數據庫與網絡傳遞的壓力是有幫助的,下面是一個案值,分別是向BLL層以IEnumerable和IQueryable方式進行數據的返回,最后在BLL層進行加工數據的操作,看代碼:
DAL層:
IQueryable方式:
public IQueryable<WebManageUsers> GetWebManageUsers(ISpecification<WebManageUsers> specification) { var linq = base.GetEntities(specification).AsQueryable() .Include(i => i.WebManageUser_WebManageRoles) .AsQueryable(); //include會增加鏈庫操作 return linq; }
IEnumerable方式:
public IEnumerable<WebManageUsers> GetWebManageUsers(ISpecification<WebManageUsers> specification) { var linq = base.GetEntities(specification).AsQueryable() .Include(i => i.WebManageUser_WebManageRoles) .AsQueryable(); //include會增加鏈庫操作 return linq; }
在BLL層進行數據重新組裝:
public List<WebManageUsers> GetWebManageUsers(DateTime? from, DateTime? to, int? status) { //Create specification UserListSpecification dateSpecification = new UserListSpecification(from, to, status); return _webManageUsers.GetWebManageUsers(dateSpecification).Select(i => new WebManageUsers_Ext { CreateDate = i.CreateDate, ManageUserID = i.ManageUserID, RealName = i.RealName, }).ToList<WebManageUsers>(); }
WEB層輸出結果,兩種方式答到的效果是一樣的,但對於一個開發人員來說,只達到效果是遠遠不夠的,因為我們必須要知道LINQ在數據庫上究竟干了什么事,即LINQ被翻譯成SQL語句是什么樣的:
IEnumerable方式:
exec sp_executesql N'SELECT [Project1].[ManageUserID] AS [ManageUserID], [Project1].[LoginName] AS [LoginName], [Project1].[Password] AS [Password], [Project1].[RealName] AS [RealName], [Project1].[Gender] AS [Gender], [Project1].[Phone] AS [Phone], [Project1].[Mobile] AS [Mobile], [Project1].[Email] AS [Email], [Project1].[AvatarUrl] AS [AvatarUrl], [Project1].[QQ] AS [QQ], [Project1].[MSN] AS [MSN], [Project1].[Rtx] AS [Rtx], [Project1].[Birthday] AS [Birthday], [Project1].[Description] AS [Description], [Project1].[DepartmentID] AS [DepartmentID], [Project1].[CreateDate] AS [CreateDate], [Project1].[UpdateDate] AS [UpdateDate], [Project1].[Operator] AS [Operator], [Project1].[Status] AS [Status], [Project1].[IntroductionURL] AS [IntroductionURL], [Project1].[WebSystemID] AS [WebSystemID], [Project1].[C1] AS [C1], [Project1].[ManageUserID1] AS [ManageUserID1], [Project1].[ManageRoleID] AS [ManageRoleID], [Project1].[CreateDate1] AS [CreateDate1] FROM ( SELECT [Extent1].[ManageUserID] AS [ManageUserID], [Extent1].[LoginName] AS [LoginName], [Extent1].[Password] AS [Password], [Extent1].[RealName] AS [RealName], [Extent1].[Gender] AS [Gender], [Extent1].[Phone] AS [Phone], [Extent1].[Mobile] AS [Mobile], [Extent1].[Email] AS [Email], [Extent1].[AvatarUrl] AS [AvatarUrl], [Extent1].[QQ] AS [QQ], [Extent1].[MSN] AS [MSN], [Extent1].[Rtx] AS [Rtx], [Extent1].[Birthday] AS [Birthday], [Extent1].[Description] AS [Description], [Extent1].[DepartmentID] AS [DepartmentID], [Extent1].[CreateDate] AS [CreateDate], [Extent1].[UpdateDate] AS [UpdateDate], [Extent1].[Operator] AS [Operator], [Extent1].[Status] AS [Status], [Extent1].[IntroductionURL] AS [IntroductionURL], [Extent1].[WebSystemID] AS [WebSystemID], [Extent2].[ManageUserID] AS [ManageUserID1], [Extent2].[ManageRoleID] AS [ManageRoleID], [Extent2].[CreateDate] AS [CreateDate1], CASE WHEN ([Extent2].[ManageUserID] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1] FROM [dbo].[WebManageUsers] AS [Extent1] LEFT OUTER JOIN [dbo].[WebManageUser_WebManageRoles] AS [Extent2] ON [Extent1].[ManageUserID] = [Extent2].[ManageUserID] WHERE (@p__linq__0 = 1) AND ([Extent1].[CreateDate] > (CASE WHEN (@p__linq__1 IS NULL) THEN @p__linq__2 ELSE @p__linq__1 END)) AND ([Extent1].[CreateDate] < (CASE WHEN (@p__linq__3 IS NULL) THEN @p__linq__4 ELSE @p__linq__3 END)) ) AS [Project1] ORDER BY [Project1].[ManageUserID] ASC, [Project1].[C1] ASC',N'@p__linq__0 bit,@p__linq__1 datetime2(7),@p__linq__2 datetime2(7),@p__linq__3 datetime2(7),@p__linq__4 datetime2(7)',@p__linq__0=1,@p__linq__1=NULL,@p__linq__2='0001-01-01 00:00:00',@p__linq__3=NULL,@p__linq__4='9999-12-31 23:59:59.9999999'
IQueryable方式:
exec sp_executesql N'SELECT [Extent1].[ManageUserID] AS [ManageUserID], [Extent1].[CreateDate] AS [CreateDate], [Extent1].[RealName] AS [RealName] FROM [dbo].[WebManageUsers] AS [Extent1] WHERE (@p__linq__0 = 1) AND ([Extent1].[CreateDate] > (CASE WHEN (@p__linq__1 IS NULL) THEN @p__linq__2 ELSE @p__linq__1 END)) AND ([Extent1].[CreateDate] < (CASE WHEN (@p__linq__3 IS NULL) THEN @p__linq__4 ELSE @p__linq__3 END))',N'@p__linq__0 bit,@p__linq__1 datetime2(7),@p__linq__2 datetime2(7),@p__linq__3 datetime2(7),@p__linq__4 datetime2(7)',@p__linq__0=1,@p__linq__1=NULL,@p__linq__2='0001-01-01 00:00:00',@p__linq__3=NULL,@p__linq__4='9999-12-31 23:59:59.9999999'
看到這里,您應該有所體會了吧,我們希望的肯定是IQueryable方式的,呵呵,它才是LINQ世界里的延時加載,下面咱們總結一下什么時候用IQueryable方
式來返回數據:
1 結果集很大,需要在BLL層去重新組裝時
2 使用take skip實現分頁時