[C#.NET][ASP.NET] Use EF6 + Telerik RadGrid custom paging in WebForm
在 Telerik + ObjectDataSource 的分頁已經可以讓開發人員減少不少代碼,但那個查詢結果不是我想要的,所以才會需要自訂分頁,搭配EF自訂分頁使用起來也不複雜,接下來演練一遍
新增一個 Telerik Web Application
在前端:
關鍵屬性
AllowPaging="True"
AllowCustomPaging="True"
還有OnNeedDataSource,這會觸發查詢
AllowPaging="True" AllowSorting="True" AllowCustomPaging="True" OnNeedDataSource="RadGrid1_NeedDataSource" ….
在後端:
透過 RadGrid.MasterTableView 本身所提供的屬性取得分頁資訊
{ if (!e.IsFromDetailTable) { var radGrid = (RadGrid)sender; //var where = RadGridHelper.GetFilterExpression(radGrid.MasterTableView, null); //var orderBy = RadGridHelper.GetOrderBy(radGrid.MasterTableView); var filter = radGrid.MasterTableView.FilterExpression; var orderBy = radGrid.MasterTableView.SortExpressions.GetSortString(); var skip = radGrid.MasterTableView.CurrentPageIndex * radGrid.MasterTableView.PageSize; var take = radGrid.MasterTableView.PageSize; var totalRowCount = 0; radGrid.DataSource = this.GetAllOrders(skip, take, orderBy, filter, out totalRowCount); if (e.RebindReason == GridRebindReason.InitialLoad || e.RebindReason == GridRebindReason.ExplicitRebind) { radGrid.VirtualItemCount = totalRowCount; } } }
有了分頁資料 EF 就可以順利撈資料
- 會在 Linq 使用到字串查詢,這裡要先從 nuget 安裝 System.Linq.Dynamic,並 using System.Linq.Dynamic;
- 這裡使用 Code first from Database
- 使用localdb,資料庫已經擺在App_Data
int startRowIndex, int maximumRows, string sortExpression, string filterExpression, out int totalRowCount) { if (string.IsNullOrWhiteSpace(sortExpression)) { sortExpression = "OrderID ASC"; } var query = this._db.Orders.OrderBy(sortExpression); if (!string.IsNullOrWhiteSpace(filterExpression)) { //filterExpression = GetNewDateExpression(filterExpression); query = query.Where(filterExpression); } totalRowCount = query.Count(); var result = query .Skip(startRowIndex) .Take(maximumRows) .AsNoTracking() .ToList(); return result; }
運行結果如下:
一個 Grid 該有的功能都有
但,當我針對 DateTime 欄位進行過濾時
會跳出以下例外,原因是 Linq To Entities 不支援 DateTime.Parse 的關係
加入中斷觀察
我需要將"(RequiredDate = DateTime.Parse(\"2/3/2015 12:00:00 AM\"))" 變成 "(RequiredDate = DateTime(2015,2,3,0,0,0))",以下代碼就是在幹這件事
{ var split = predicate.Split(chars, StringSplitOptions.RemoveEmptyEntries); if (split.Count() > 1) { StringBuilder sb = new StringBuilder(); foreach (var element in split) { DateTime result; if (DateTime.TryParse(element, out result)) { var format = string.Format("DateTime({0},{1},{2},{3},{4},{5})", result.Year, result.Month, result.Day, result.Hour, result.Minute, result.Millisecond); sb.Append(format); } else { sb.Append(element); } } predicate = sb.ToString(); } return predicate; }
再次調用,filterExpression 果然已經變成我想要的 Pattern
最後執行過濾結果
用 SQL Profiler 觀察最終 SQL 結果,很好,真的有分頁,真的有過濾
透 SQL Profiler 觀察,你會發現 RadGrid 不是用 Top "真的"幫你分頁
附帶一提 升級到 EF 6.1.2 後 Generate 出來的分頁的語法,變了
文章出自:http://www.dotblogs.com.tw/yc421206/archive/2015/02/09/149434.aspx
專案位置:https://dotblogsamples.codeplex.com/SourceControl/latest#Simple.RadGridPaging/
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET