[C#.NET][ASP.NET] Use EF6 + Telerik RadGrid custom paging in WebForm

[C#.NET][ASP.NET] Use EF6 + Telerik RadGrid custom paging in WebForm

在 Telerik + ObjectDataSource 的分頁已經可以讓開發人員減少不少代碼,但那個查詢結果不是我想要的,所以才會需要自訂分頁,搭配EF自訂分頁使用起來也不複雜,接下來演練一遍

新增一個 Telerik Web Application

image

 

在前端:

關鍵屬性

AllowPaging="True"

AllowCustomPaging="True"

還有OnNeedDataSource,這會觸發查詢


    AllowPaging="True" 
    AllowSorting="True" 
    AllowCustomPaging="True" 
    OnNeedDataSource="RadGrid1_NeedDataSource" 
….

 

完整代碼請參考:https://dotblogsamples.codeplex.com/SourceControl/latest#Simple.RadGridPaging/Simple.RadGridPaging/Default.aspx

 

 

在後端:

透過 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 就可以順利撈資料

  1. 會在 Linq 使用到字串查詢,這裡要先從 nuget 安裝 System.Linq.Dynamic,並 using System.Linq.Dynamic;
  2. 這裡使用 Code first from Database
  3. 使用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;
}

 

完整代碼請參考:https://dotblogsamples.codeplex.com/SourceControl/latest#Simple.RadGridPaging/Simple.RadGridPaging/Default.aspx.cs

 

 

運行結果如下:

一個 Grid 該有的功能都有

image

 

 

但,當我針對 DateTime 欄位進行過濾時

image

 

 

會跳出以下例外,原因是 Linq To Entities 不支援 DateTime.Parse 的關係

image

 

 

 

加入中斷觀察

image

 

我需要將"(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

image

 

 

最後執行過濾結果

image

 

用 SQL Profiler 觀察最終 SQL 結果,很好,真的有分頁,真的有過濾

image

 

 

 

 

透 SQL Profiler 觀察,你會發現 RadGrid 不是用 Top "真的"幫你分頁

 

附帶一提 升級到 EF 6.1.2 後 Generate 出來的分頁的語法,變了

image

 


文章出自: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

Image result for microsoft+mvp+logo