IPagedList.MVC,设置总大小?

时间:2014-04-23 19:10:47

标签: c# asp.net asp.net-mvc asp.net-mvc-4

我正在使用asp.net MVC 5构建一个应用程序,并使用IPagedList.MVC版本4.5.0.0,AutoMapper和Entity Framework构建一个网格。

在项目中,我有一个BusinessLayer,这是我的Action所说的,因为我不希望Action方法直接与Entity Framework对话。所以我的BLL有以下方法:

        public IPagedList<ActiveContractViewModel> GetAllContracts(string regNumFilter, int page)
    {
        var lstcontractViewModel = new List<ActiveContractViewModel>();
        using (ActiveContractRepository activeContractRepos = new ActiveContractRepository(new UnitOfWork()))
        {
            var activeContractList = activeContractRepos.All.OrderByDescending(x => x.Id).Include(c => c.Contractor);

            if (regNumFilter.Trim().Length > 0)
            {
                activeContractList = activeContractRepos.All.Where(x => x.RegistrationNumber.Contains(regNumFilter)).OrderByDescending(x => x.Id).Include(c => c.Contractor);
            }

            foreach (var activeContract in activeContractList)
            {
                Mapper.CreateMap<DomainClasses.ActiveContract, ActiveContractViewModel>().ForMember(dest => dest.ContractorModel, opts => opts.MapFrom(src => new ContractorViewModel
                    {
                        Id = src.Contractor.Id,
                        Name = src.Contractor.Name,
                        ContactPerson = src.Contractor.ContactPerson,
                        Phone = src.Contractor.Phone,
                        Fax = src.Contractor.Fax,
                        Address = src.Contractor.Address,
                        VendorNumber = src.Contractor.VendorNumber,
                        FederalTaxId = src.Contractor.FederalTaxId
                    }
                ));

                Mapper.AssertConfigurationIsValid();
                lstcontractViewModel.Add(Mapper.Map<ActiveContractViewModel>(activeContract));
            }
        }

        return lstcontractViewModel.ToPagedList(page, 20);
    }

我将我的ActiveContract类(从Entity Framework)映射到模型(ActiveContractVieWModel),它工作正常,返回数据并进行分页工作。但是我注意到在调试时foreach循环也会遍历所有记录,如果我有2500条记录,它会循环遍历所有构建大型列表,然后在ToPageList方法上使用。

有没有更好的解决方法,所以我可以构建我的模型并用我需要的20条记录填充它并让IPagedList知道总大小?

4 个答案:

答案 0 :(得分:3)

我最后再看了一下IPageList.MVC,看到作者发布了这个: https://github.com/troygoode/pagedlist#example-2-manual-paging

“在某些情况下,您无法访问能够创建IQueryable的内容,例如使用.Net的内置MembershipProvider的GetAllUsers方法时。此方法提供分页,但不是通过IQueryable。幸运的是PagedList仍然有你的背(注意)使用StaticPagedList):“

我转而使用StaticPagedList,现在效果更好,只需抓取我想要的记录数量,并且分页也能正常工作。

答案 1 :(得分:1)

这是因为您正在检索所有项目。在LINQ查询中,您只是按regNumFilter

进行过滤
var activeContractList = activeContractRepos
    .All
    .OrderByDescending(x => x.Id)
    .Include(c => c.Contractor);

activeContractList = activeContractRepos
    .All
    .Where(x => x.RegistrationNumber.Contains(regNumFilter))
    .OrderByDescending(x => x.Id)
    .Include(c => c.Contractor);

要检索特定行数(在每种情况下每页20个项目),请在迭代结果之前使用Skip()Take()

示例代码:

var activeContractList = activeContractList 
    .Skip(20 * page)
    .Take(20);

foreach (var activeContract in activeContractList)
{
    ....
}

答案 2 :(得分:0)

我没有使用自动播放器,只有valueinjecter

我所做的是“映射”IList<TModel>IList<TViewModel>然后你就没有代码了。它会更干净。

PagedList不知道TEntity,它只是分页。不要忘记分页是懒惰的。

使用Valueinjecter我有以下代码:

https://github.com/fatagun/NetCollab/blob/master/NetCollab.Web/Mappers/Mapper.cs

答案 3 :(得分:0)

我认为你需要的是AutoMapper Queryable-Extensions

当您使用IEnumerable<T>接口时,实现了下划线实体查询。 因此,在ToPagedList&#34;采取&#34;之前,查询将在整个表中运行。和&#34;跳过&#34;一些页面。相反,您必须使用IQueryable<T>变体。

  

当使用ORM(如NHibernate或Entity Framework)和AutoMapper的标准Mapper.Map函数时,您可能会注意到当AutoMapper尝试映射时,ORM将查询图形中所有对象的所有字段结果到目的地类型