C# 为什么,ToPagedList工作得这么慢?
我想知道分页在从数据库中提取的数据集上到底是如何工作的。在我的示例中,我对一个表进行一些搜索和过滤,并将这些值传递给控制器。我还将C# 为什么,ToPagedList工作得这么慢?,c#,asp.net-mvc,C#,Asp.net Mvc,我想知道分页在从数据库中提取的数据集上到底是如何工作的。在我的示例中,我对一个表进行一些搜索和过滤,并将这些值传递给控制器。我还将页面传递给.ToPagedList 我注意到分页速度很慢(当我将页面切换到下一个页面时,这需要时间)。这就是为什么我要问.ToPagedList是如何工作的,使用它有什么好处 在我的示例中,每当我更改页码时,就会调用索引操作并建立到数据库的连接。对整个数据集进行过滤,然后结果变成页面列表。然后我可以看到我在给定的页面上,但这确实需要时间 当我再次更改页面时,会调用索引
页面
传递给.ToPagedList
我注意到分页速度很慢(当我将页面切换到下一个页面时,这需要时间)。这就是为什么我要问.ToPagedList
是如何工作的,使用它有什么好处
在我的示例中,每当我更改页码时,就会调用索引
操作并建立到数据库的连接。对整个数据集进行过滤,然后结果变成页面列表
。然后我可以看到我在给定的页面上,但这确实需要时间
当我再次更改页面时,会调用索引操作,它会连接到数据库并绘制数据集,过滤并将结果返回给给定页面。也许我错了,但就性能而言,这是一种非常慢的方法,而且会消耗大量内存
视图:
接口:
public class DocumentsService : IDocuments
{
private MYdb _context;
public DocumentsService(MYdb context)
{
_context = context;
}
public IEnumerable<DocumentsTableSQL> GetAll()
{
return _context.DocumentsTableSQL.AsNoTracking();
}
}
公共类文档服务:IDocuments
{
私有MYdb_上下文;
公共文档服务(MYdb上下文)
{
_上下文=上下文;
}
公共IEnumerable GetAll()
{
return _context.DocumentsTableSQL.AsNoTracking();
}
}
正如您每次更改页面时所看到的,然后调用Index
操作并查询数据库,这会耗费时间和内存。我认为PagedList
在某种程度上保留了结果,并且在页面更改时不允许一直查询数据库
编辑:
我在控制器代码和接口中添加了``````文档``以显示如何从数据库中提取数据。我将依赖注入控制器。我认为问题在于如何组合选择。在执行.Select(s=>newdocumentsmodel…)时,该列表将解析到内存中,并从数据库中获取所有行。OrderBy()和ToPagedList()都在内存中的所有行上执行。下面是在我的系统上使用本地数据库的应用程序。表read是包含许多行的课程 执行下面的代码将得到以下结果:
代码如下:
using System;
using System.Diagnostics;
namespace ToPagedList
{
class Program
{
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
sw.Start();
var list1 = Repository.GetCourses1();
sw.Stop();
Console.WriteLine($"Getting list 1 took {sw.ElapsedMilliseconds} milliseconds");
sw.Reset();
sw.Start();
var list2 = Repository.GetCourses2();
sw.Stop();
Console.WriteLine($"Getting list 2 took {sw.ElapsedMilliseconds} milliseconds");
Console.ReadKey();
}
}
}
下面代码的不同之处在于将.Select()语句放在何处
- 在第一个列表中,在进行排序之前,整个表将被读入Select()中
- 在第二个列表中,只读取表中的15行。OrderBy()在数据库中完成,而不是在内存中完成
使用系统;
使用System.Collections.Generic;
使用System.Linq;
命名空间ToPagedList
{
公共类存储库
{
公共静态列表GetCourse1(字符串school=null,字符串code=null,字符串title=null,int page=0,int count=15)
{
var courses=新的DocumentModelEntities();
返回courses.Where(course=>string.IsNullOrEmpty(代码)| | course.CourseCode.Contains(代码))
.Where(course=>String.IsNullOrEmpty(title)| | course.title.Contains(title))
.Where(w=>String.IsNullOrEmpty(school)| | w.school==school)
//从这里,使用where子句从DB读取表
.选择(s=>新文档模型
{
Code=Code.Trim(),
Title=s.Title
})
.OrderBy(o=>o.Code)
.跳过(第*页计数)
.记(数)
.ToList();
}
公共静态列表GetCourse2(字符串school=null,字符串code=null,字符串title=null,int page=0,int count=15)
{
var courses=新的DocumentModelEntities();
返回courses.Where(course=>string.IsNullOrEmpty(代码)| | course.CourseCode.Contains(代码))
.Where(course=>String.IsNullOrEmpty(title)| | course.title.Contains(title))
.Where(w=>String.IsNullOrEmpty(school)| | w.school==school)
.OrderBy(course=>course.CourseCode)
.跳过(第*页计数)
.记(数)
//从这里,使用where子句、order by、skip和take从数据库中读取表
.选择(s=>新文档模型
{
Code=Code.Trim(),
Title=s.Title
})
.ToList();
}
}
}
我认为问题在于如何撰写选择。在执行.Select(s=>newdocumentsmodel…)时,该列表将解析到内存中,并从数据库中获取所有行。OrderBy()和ToPagedList()都在内存中的所有行上执行。下面是在我的系统上使用本地数据库的应用程序。表read是包含许多行的课程
执行下面的代码将得到以下结果:
代码如下:
using System;
using System.Diagnostics;
namespace ToPagedList
{
class Program
{
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
sw.Start();
var list1 = Repository.GetCourses1();
sw.Stop();
Console.WriteLine($"Getting list 1 took {sw.ElapsedMilliseconds} milliseconds");
sw.Reset();
sw.Start();
var list2 = Repository.GetCourses2();
sw.Stop();
Console.WriteLine($"Getting list 2 took {sw.ElapsedMilliseconds} milliseconds");
Console.ReadKey();
}
}
}
下面代码的不同之处在于将.Select()语句放在何处
- 在第一个列表中,在进行排序之前,整个表将被读入Select()中
- 在第二个列表中,只读取表中的15行。OrderBy()在数据库中完成,而不是在内存中完成
使用系统;
使用System.Collections.Generic;
使用System.Linq;
命名空间ToPagedList
{
公共类存储库
{
公共静态列表GetCourse1(字符串school=null,字符串code=null,字符串title=null,int page=0,int count=15)
{
var courses=新的DocumentModelEntities();
Getting list 1 took 2289 milliseconds
Getting list 2 took 46 milliseconds
using System;
using System.Diagnostics;
namespace ToPagedList
{
class Program
{
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
sw.Start();
var list1 = Repository.GetCourses1();
sw.Stop();
Console.WriteLine($"Getting list 1 took {sw.ElapsedMilliseconds} milliseconds");
sw.Reset();
sw.Start();
var list2 = Repository.GetCourses2();
sw.Stop();
Console.WriteLine($"Getting list 2 took {sw.ElapsedMilliseconds} milliseconds");
Console.ReadKey();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
namespace ToPagedList
{
public class Repository
{
public static List<DocumentsModel> GetCourses1(string school = null, string code = null, string title = null, int page = 0, int count = 15)
{
var courses = new DocumentModelEntities().Course;
return courses.Where(course => string.IsNullOrEmpty(code) || course.CourseCode.Contains(code))
.Where(course => String.IsNullOrEmpty(title) || course.Title.Contains(title))
.Where(w => String.IsNullOrEmpty(school) || w.School == school)
// From here your table is read from the DB using the where clauses
.Select(s => new DocumentsModel
{
Code = code.Trim(),
Title = s.Title
})
.OrderBy(o => o.Code)
.Skip(page * count)
.Take(count)
.ToList();
}
public static List<DocumentsModel> GetCourses2(string school = null, string code = null, string title = null, int page = 0, int count = 15)
{
var courses = new DocumentModelEntities().Course;
return courses.Where(course => string.IsNullOrEmpty(code) || course.CourseCode.Contains(code))
.Where(course => String.IsNullOrEmpty(title) || course.Title.Contains(title))
.Where(w => String.IsNullOrEmpty(school) || w.School == school)
.OrderBy(course => course.CourseCode)
.Skip(page * count)
.Take(count)
// From here your table is read from the DB using the where clauses, order by, skip and take
.Select(s => new DocumentsModel
{
Code = code.Trim(),
Title = s.Title
})
.ToList();
}
}
}