首页 > 解决方案 > Asp.net 核心问题中的分页,仅获取 10 项而不使其更快?

问题描述

我正在尝试改善我在 Asp.net 核心网络应用程序中的分页...我只想在每个页面加载 10 条记录。我第一次这样做时,我正在加载所有记录,然后最后我只获得了其中的 10 条并发送到视图,这非常糟糕,因为我获得了两次数据,而我第一次获得了所有记录...... (下面的示例)我现在的方法实际上是只获取 10 个项目.. 但在此之前我将它们全部计算在内,以便我可以获得总页数...(下面的示例)

在另一个没有分页的视图中,我有 13 条记录,我得到了所有记录,因为我或多或少地花费了 100-300 毫秒......所以我的意思是,用秒的方法,为什么我的时间大约是 2,60秒?不应该是最多 1 秒吗?此外,第一种方法和第二种方法之间的差异是最小的,我在桌子上有 8000 多条记录......我做错了什么?这次如何改进?

我的第一种方法的代码:

ViewModelCentroCusto vmcc = new ViewModelCentroCusto()
            {
                CurrentPage = page,
                FirstPageShow = Math.Max(2, page - NUMBER_OF_PAGES_BEFORE_AND_AFTER),
                Departamentos = selectListdepartamentos,
                Empresas = selectListEmpresas,
                Anos = selectListAnos.GroupBy(x => x.Text).Select(x => x.First()).OrderBy(o => o.Text).ToList()
            };

            //atualizacao do viewModel com base em filtros, pesquisas e paginacoess
            if (!String.IsNullOrEmpty(searchString))
            {

                vmcc.CentroCustos = _context.RH_CentroCusto
                .Where(p => anoSelecionado.Any() ? anoSelecionado.Contains(p.Ano.ToString()) : true)
                .Where(p => departmentoSelecionado.Any() ? departmentoSelecionado.Contains(p.Departamento.Departamento) : true)
                .Where(p => empresaSelecionada.Any() ? empresaSelecionada.Contains(p.Empresa.Codigo) : true)
                .Where(p => p.CentroCusto.Contains(searchString) || p.Descricao.Contains(searchString));
                
            }
            else {


                vmcc.CentroCustos = _context.RH_CentroCusto
               .Where(p => anoSelecionado.Any() ? anoSelecionado.Contains(p.Ano.ToString()) : true)
               .Where(p => departmentoSelecionado.Any() ? departmentoSelecionado.Contains(p.Departamento.Departamento) : true)
               .Where(p => empresaSelecionada.Any() ? empresaSelecionada.Contains(p.Empresa.Codigo) : true);
               
            }

            vmcc.TotalPages = (int)Math.Ceiling((decimal)vmcc.CentroCustos.Count() / NUMBER_OF_PRODUCTS_PER_PAGE);
            vmcc.CentroCustos = vmcc.CentroCustos.Skip((page - 1) * NUMBER_OF_PRODUCTS_PER_PAGE);
            vmcc.CentroCustos = vmcc.CentroCustos.Take(NUMBER_OF_PRODUCTS_PER_PAGE);
            vmcc.LastPageShow = Math.Min(vmcc.TotalPages, page + NUMBER_OF_PAGES_BEFORE_AND_AFTER);
            vmcc.FirstPage = 1;
            vmcc.LastPage = vmcc.TotalPages;
            vmcc.CurrentSearchString = searchString;
            vmcc.DepartmentoSelecionado = departmentoSelecionado;
            vmcc.AnoSelecionado = anoSelecionado;
            vmcc.EmpresaSelecionada = empresaSelecionada;

            return View(vmcc);

这是我得到所有记录的地方,然后我得到了其中的 10 个,至少对我来说没有意义,所以我改为:

ViewModelCentroCusto vmcc = new ViewModelCentroCusto()
            {
                CurrentPage = page,
                FirstPageShow = Math.Max(2, page - NUMBER_OF_PAGES_BEFORE_AND_AFTER),
                Departamentos = selectListdepartamentos,
                Empresas = selectListEmpresas,
                Anos = selectListAnos.GroupBy(x => x.Text).Select(x => x.First()).OrderBy(o => o.Text).ToList()
            };

            //atualizacao do viewModel com base em filtros, pesquisas e paginacoess
            if (!String.IsNullOrEmpty(searchString))
            {
                number = _context.RH_CentroCusto
                .Where(p => anoSelecionado.Any() ? anoSelecionado.Contains(p.Ano.ToString()) : true)
                .Where(p => departmentoSelecionado.Any() ? departmentoSelecionado.Contains(p.Departamento.Departamento) : true)
                .Where(p => empresaSelecionada.Any() ? empresaSelecionada.Contains(p.Empresa.Codigo) : true)
                .Where(p => p.CentroCusto.Contains(searchString) || p.Descricao.Contains(searchString))
                .Count();

                vmcc.CentroCustos = _context.RH_CentroCusto
                .Where(p => anoSelecionado.Any() ? anoSelecionado.Contains(p.Ano.ToString()) : true)
                .Where(p => departmentoSelecionado.Any() ? departmentoSelecionado.Contains(p.Departamento.Departamento) : true)
                .Where(p => empresaSelecionada.Any() ? empresaSelecionada.Contains(p.Empresa.Codigo) : true)
                .Where(p => p.CentroCusto.Contains(searchString) || p.Descricao.Contains(searchString))
                .Skip((page - 1) * NUMBER_OF_PRODUCTS_PER_PAGE)
                .Take(NUMBER_OF_PRODUCTS_PER_PAGE); 
            }
            else {
                number = _context.RH_CentroCusto
               .Where(p => anoSelecionado.Any() ? anoSelecionado.Contains(p.Ano.ToString()) : true)
               .Where(p => departmentoSelecionado.Any() ? departmentoSelecionado.Contains(p.Departamento.Departamento) : true)
               .Where(p => empresaSelecionada.Any() ? empresaSelecionada.Contains(p.Empresa.Codigo) : true)
               .Count();

                vmcc.CentroCustos = _context.RH_CentroCusto
               .Where(p => anoSelecionado.Any() ? anoSelecionado.Contains(p.Ano.ToString()) : true)
               .Where(p => departmentoSelecionado.Any() ? departmentoSelecionado.Contains(p.Departamento.Departamento) : true)
               .Where(p => empresaSelecionada.Any() ? empresaSelecionada.Contains(p.Empresa.Codigo) : true)
               .Skip((page - 1) * NUMBER_OF_PRODUCTS_PER_PAGE)
               .Take(NUMBER_OF_PRODUCTS_PER_PAGE);
            }

            vmcc.TotalPages = (int)Math.Ceiling(number / NUMBER_OF_PRODUCTS_PER_PAGE);
            //vmcc.CentroCustos = vmcc.CentroCustos.Skip((page - 1) * NUMBER_OF_PRODUCTS_PER_PAGE);
            //vmcc.CentroCustos = vmcc.CentroCustos.Take(NUMBER_OF_PRODUCTS_PER_PAGE);
            vmcc.LastPageShow = Math.Min(vmcc.TotalPages, page + NUMBER_OF_PAGES_BEFORE_AND_AFTER);
            vmcc.FirstPage = 1;
            vmcc.LastPage = vmcc.TotalPages;
            vmcc.CurrentSearchString = searchString;
            vmcc.DepartmentoSelecionado = departmentoSelecionado;
            vmcc.AnoSelecionado = anoSelecionado;
            vmcc.EmpresaSelecionada = empresaSelecionada;

            return View(vmcc);

现在我只得到 10 我想,那为什么不变得更快呢?任何帮助表示赞赏

标签: c#asp.net-corepagination

解决方案


在不知道您的数据库、行数、系统规格和其他实现的情况下,我的猜测是因为Count

                number = _context.RH_CentroCusto
                .Where(p => anoSelecionado.Any() ? anoSelecionado.Contains(p.Ano.ToString()) : true)
                .Where(p => departmentoSelecionado.Any() ? departmentoSelecionado.Contains(p.Departamento.Departamento) : true)
                .Where(p => empresaSelecionada.Any() ? empresaSelecionada.Contains(p.Empresa.Codigo) : true)
                .Where(p => p.CentroCusto.Contains(searchString) || p.Descricao.Contains(searchString))
                .Count();

需要评估此查询并扫描所有数据库行的总数。这将花费与原始时间几乎相同的时间:

                vmcc.CentroCustos = _context.RH_CentroCusto
                .Where(p => anoSelecionado.Any() ? anoSelecionado.Contains(p.Ano.ToString()) : true)
                .Where(p => departmentoSelecionado.Any() ? departmentoSelecionado.Contains(p.Departamento.Departamento) : true)
                .Where(p => empresaSelecionada.Any() ? empresaSelecionada.Contains(p.Empresa.Codigo) : true)
                .Where(p => p.CentroCusto.Contains(searchString) || p.Descricao.Contains(searchString));
                

推荐阅读