我们有一个项目列表,可能有也可能没有子项目集合。我们的报告需要包含除子项目的父项目之外的所有项目。
我需要将此页面分成25行的页面。但是,如果子项目出现在该页面上,则该项目的所有子项目必须出现在同一页面上。因此,如有必要,可能会出现超过25个项目。
我到目前为止
var pagedProjects = db.Projects.Where(x => !x.SubProjects.Any()).Skip(
(pageNo -1) * pageSize).Take(pageSize);
显然,这不符合要求的第二部分。
作为屁股的进一步痛苦,我需要对报告进行寻呼机控制。所以我需要能够计算总页数。
我可以遍历整个项目表,但性能会受到影响。任何人都可以提出分页解决方案吗?
编辑 - 我应该提一下,SubProjects通过自引用外键加入到项目中,所以整个批次,父项目,子项目和所有项目都以IQueryable<Project>
的形式返回。
答案 0 :(得分:1)
也许尝试分页父项目,但只显示其子项。
var pagedParentProjects = db.Projects.Where(x => x.SubProjects.Any()).Skip(pageNo-1) * pageSize).Take(pageSize);
然后在显示数据时循环浏览该项目的子项目。
@model IEnumerable<Project>
@foreach (Project project in Model)
{
<div>
@foreach (Project subProject in project.SubProjects)
{
<span>subProject.Name</span>
}
</div>
}
现在所有具有相同父级的子项目将位于同一页面上。
答案 1 :(得分:1)
通过从查询中抽象出问题,我发现更容易处理分页。这是我使用的解决方案的来源。这将使您的代码更直接,并将所有分页逻辑转换为对ToPagedList(int index, int pageSize)
的单个简单调用。我不是百分百肯定,但我相信我最初从Rob Conery的Kona项目中获取了这个来源(他的博客位于http://blog.wekeroad.com/)。
助手类
public static class Pagination
{
public static PagedList<T> ToPagedList<T>(this IEnumerable<T> source, int index)
{
return new PagedList<T>(source.AsQueryable(), index, 10);
}
public static PagedList<T> ToPagedList<T>(this IEnumerable<T> source, int index, int pageSize)
{
return new PagedList<T>(source.AsQueryable(), index, pageSize);
}
public static PagedList<T> ToPagedList<T>(this IQueryable<T> source, int index, int pageSize)
{
return new PagedList<T>(source, index, pageSize);
}
public static PagedList<T> ToPagedList<T>(this IQueryable<T> source, int index)
{
return new PagedList<T>(source, index, 10);
}
}
接口
public interface IPagedList<T> : IList<T>, IPagedList
{
}
public interface IPagedList
{
int TotalCount { get; set; }
int TotalPages { get; set; }
int PageIndex { get; set; }
int PageSize { get; set; }
bool IsPreviousPage { get; }
bool IsNextPage { get; }
}
PagedList实施
public class PagedList<T> : List<T>, IPagedList<T>
{
public PagedList(IQueryable<T> source, int index, int pageSize)
{
int total = source.Count();
this.TotalCount = total;
this.TotalPages = total/pageSize;
if (total%pageSize > 0)
TotalPages++;
this.PageSize = pageSize;
this.PageIndex = index;
this.AddRange(source.Skip(index*pageSize).Take(pageSize).ToList());
}
public PagedList(IEnumerable<T> source, int total, int index, int pageSize)
{
this.TotalCount = total;
this.TotalPages = total/pageSize;
if (total%pageSize > 0)
TotalPages++;
this.PageSize = pageSize;
this.PageIndex = index;
this.AddRange(source);
}
#region IPagedList<T> Members
public int TotalPages { get; set; }
public int TotalCount { get; set; }
public int PageIndex { get; set; }
public int PageSize { get; set; }
public bool IsPreviousPage
{
get { return (PageIndex > 0); }
}
public bool IsNextPage
{
get { return (PageIndex*PageSize) <= TotalCount; }
}
#endregion
}
答案 2 :(得分:0)
对我来说听起来像是这样的:
var pagedProjects = db.Projects.Skip((pageNo - 1) * pageSize).Take(pageSize);
var expandedPagedProjects = from p in pagedProjects
group p.subprojects by p into grp
select grp;
这会使expandedPagedProjects成为IEnumerable<IGrouping<Project, T>>
,其中T是子项目集合的类型(例如,List<SubProject>
)。所以基本上你要做的就是将项目分成25个组,然后扩展子项目集合并将它们与父项目分组。然后,您可以根据需要显示它们,可能是通过使用嵌套的foreach
循环遍历它们。