了解PagedList mvc和实体框架(慢速查询)

时间:2018-01-01 13:15:03

标签: c# mysql asp.net-mvc entity-framework pagedlist

我在MySQL数据库中有一个表,有几千条记录。在我的网页上,我使用PagedList一次显示10条记录。我通常会这样调用数据。

using (var ctx = new mydbEntities())
{
    var customers = ctx.customers.OrderBy(o => o.ID).ToPagedList(1,10);
}

如果我要查看它生成的SQL,我是否正确地说ToPagedList只会从数据库中选择10行,而不是在从结果中取10之前返回所有内容?

在某些情况下,我使用原始SQL,因为查询非常复杂,并且根据特定条件构建为字符串。一个简化的例子。

using (var ctx = new mydbEntities())
{
    List<MySqlParameter> parameters = new List<MySqlParameter>();
    string strQry = "select * from visitor;";                
    var customers = ctx.Database.SqlQuery<customer>(strQry, parameters.ToArray()).OrderByDescending(o => o.ID).ToPagedList(1,10);
}

我想这会在应用分页之前返回所有记录吗?

是否有一种有效的方法将PagedList应用于后一个示例?

谢谢你们。

2 个答案:

答案 0 :(得分:2)

我认为为了更好地帮助您解决问题,看看会很高兴 在两个查询的生成的sql中。

从我在PagedList的回购中看到的:

它将对数据库进行2次调用:

  1. 将采用提供的查询计数
  2. 将使用正确的take和skip来获取实际查询。
  3. 现在你的第二个查询,如果你想获得更好的性能,将代码编写为原始sql查询以使分页功能如@Ivan Stoev指出的那样可能更有效。

    无论哪种方式,当您使用PagedList库时,两个查询都将执行两次。

    虽然使用.Database.SqlQuery<customer>时会收到警报,但您获得的结果并未缓存在Entity Framework中,即使它们是有效的实体对象,也不会被跟踪。 有关该检查的更多信息:

    1. Database.SqlQuery Method

    2. DbRawSqlQuery Class

答案 1 :(得分:0)

var customers = ctx.customers.OrderBy(o => o.ID).ToPagedList(1,10);

使用此查询; Linq to实体将查询翻译为类似select * from customers order by ID OFFSET 1 ROWS FETCH NEXT 10 ROWS ONLY的内容,这是您想要的。

var customers = ctx.Database.SqlQuery<customer>(strQry, parameters.ToArray()).OrderByDescending(o => o.ID).ToPagedList(1,10);

使用此查询; SQL Server已获取strQry查询,并开始记录检索。因此,期望的OrderByPagination操作在内存中执行。

这里有两个选项;

  1. 使用Linq To Entity查询并翻译ToPagedList IQueryable表格
  2. 或修改strQry查询以使用类似的内容执行排序和分页

    select * from table order by cl1 OFFSET x ROWS FETCH NEXT y ROWS ONLY