是否可以使用ServiceStack进行服务器端分页,并通过带有KendoUI网格的JSON / AJAX使用它?我有大量需要分页的数据(30,000多行)。我需要电线上最小的有效载荷。 Kendo网格的所有示例都显示了客户端设置的分页参数,但ServiceStack似乎没有使用它们。这让我担心一切都将通过网络发送。这是在ASP.NET MVC4应用程序中运行。
答案 0 :(得分:3)
你说得对,大多数KendoUI示例都使用客户端分页,它首先通过网络发送整个数据集。几个月前我遇到了这个问题,并最终选择了一种不同的整体方法,但我有所拥有的。
您可以采取以下两种基本方法之一:
DataSource
设置配置KendoUI transport
,将KendoUI查询更改为与ServiceStack更加协作的查询。我使用全局请求过滤器使用#2。这是不完整的代码,但其想法是处理分页,排序和过滤。您可以保持Page
,PageSize
,Skip
和Take
参数,然后手动应用分页。
首先,DTO。对于任何ServiceStack DTO,也从该基类继承。我知道这种情况在Mythz(非常有效)opinion on DTO design的情况下过得很快,但这种方法在其他方面不会起作用。
public class KendoQueryBase : IKendoFilter, IKendoSort, IKendoPaged
{
public FilterTerm Filter { get; set; }
public List<SortTerm> Sort { get; set; }
public int? Page { get; set; }
public int? PageSize { get; set; }
public int? Skip { get; set; }
public int? Take { get; set; }
}
然后使用全局请求过滤器将请求转换为可由ServiceStack解释的格式。同样,如果您只是进行分页,则可能不需要这样做。它也不完整,但显示了一个不错的起点。
class KendoQueryPlugin : IPlugin
{
public void Register(IAppHost appHost)
{
appHost.GlobalRequestFilters.Add((req, resp, dto) =>
{
if (dto is KendoQueryBase)
{
KendoQueryBase qb = dto as KendoQueryBase;
if (qb.Sort == null) qb.Sort = new List<SortTerm>();
Dictionary<string, string> qs = req.QueryString.ToDictionary();
// Create the Sort Terms
var i = 0;
while (qs.ContainsKey("sort[{0}][field]".Fmt(i)))
{
qb.Sort.Add(new SortTerm()
{
Field = qs["sort[{0}][field]".Fmt(i)],
Dir = qs["sort[{0}][dir]".Fmt(i)]
});
i++;
}
i = 0;
}
});
}
}
为了进一步解决分页问题,我还编写了一个帮助扩展,利用ServiceStack.OrmLite库并将分页插入SqlExpression
:
public static class PagingExtensions
{
public static SqlExpression<T> Page<T>(this SqlExpression<T> exp, int? page, int? pageSize)
{
if (!page.HasValue || !pageSize.HasValue)
return exp;
if (page <= 0) throw new ArgumentOutOfRangeException("page", "Page must be a number greater than 0.");
if (pageSize <= 0) throw new ArgumentOutOfRangeException("pageSize", "PageSize must be a number greater than 0.");
int skip = (page.Value - 1) * pageSize.Value;
int take = pageSize.Value;
return exp.Limit(skip, take);
}
}
您可以将它与上述DTO模式一起使用,如下所示:
if (!request.Page.HasValue) request.Page = 1;
if (!request.PageSize.HasValue || request.PageSize < 0 || request.PageSize > 100)
request.PageSize = 10;
var exp = Db.From<Your Database Object>
....
var results = Db.Select<YourDTO>(exp.Page(request.Page, request.PageSize)),