PagedList.Mvc returns 来自 table 的所有记录
PagedList.Mvc returns all records from the table
我的通用存储库中有以下功能。 var list = query.ToPagedList(pageNumber, pageSizeNumber);
行有两个问题
public IEnumerable<T> GetPagedListDbContext(string searchFieldName, string searchText, string searchOperator, string sortFieldName, int? page, int? pageSize)
{
int pageSizeNumber = (pageSize ?? 20);
int pageNumber = (page ?? 1);
string sql = string.Empty;
sql = string.Format("Select * From {0} q ", typeof(T).Name);
switch (searchOperator)
{
case "Starts With":
sql += string.Format("Where q.{0} like '{1}%' ", searchFieldName, searchText);
break;
case "Ends With":
sql += string.Format("Where q.{0} like '%{1}' ", searchFieldName, searchText);
break;
case "Contains":
sql += string.Format("Where q.{0} like '%{1}%' ", searchFieldName, searchText);
break;
case "Equal To":
sql += string.Format("Where q.{0} == '{1}' ", searchFieldName, searchText);
break;
case "Not Equal To":
sql += string.Format("Where q.{0} != '{1}' ", searchFieldName, searchText);
break;
}
if (sortFieldName == null)
{
sql += "Order By q.Id ";
}
else
{
sql += string.Format("Order By q.{0} ", sortFieldName);
}
// RepoDbSet is DbSet
DbSqlQuery<T> query = RepoDbSet.SqlQuery(sql);
var list = query.ToPagedList(pageNumber, pageSizeNumber);
return list;
}
- 它 returns 来自 table 的所有记录。 (Sql 追踪如下)
它执行相同的查询两次。
Sql 跟踪
事件 Class 文本数据
RPC:已完成执行 sp_reset_connection
SQL:BatchCompleted Select * 来自图书 q 排序依据 q.Id
RPC:已完成执行 sp_reset_connection
SQL:BatchCompleted Select * 来自图书 q 排序依据 q.Id
跟踪已停止
问题:
为什么在没有 Skip
和 Take
的情况下执行查询(例如 OFFSET 0 ROWS FETCH NEXT 20 ROWS ONLY
)?
为什么要执行两次?
当我检查最后一行 return list
时,它的总计数为 20,而不是 table 中的总行数,并且没有再次访问数据库。查询的怎么样了?
是否可以使用 Linq 执行相同的过程?
在幕后,ToPagedList 将执行两个操作:
获取总记录数(知道有多少页):
query.Count()
获取当前页记录:
query.Skip((pageNumber - 1) * pageSize).Take(pageSize)
这些导致您看到的两个查询。
它将运行你的自定义,串联SQL,在内存中创建一个对象集合,然后对集合执行LINQ to objects .
这是了解 LINQ 的重要一点。如果该集合支持 IQueryable,则该集合将传递一个表达式树,它可以仔细地将其转换为适当的 SQL。
如果它只支持 IEnumerable,那么查询将在内存中的对象集合上进行操作。
显然 DbSqlQuery 没有实现 IQueryable。
而不是串联 SQL,您应该公开底层 table 对象(EntityFramework?Linq2Sql?什么 ORM?)和 运行 您对此的查询:
var books = context.Books; //or whatever
var query = books.Where(b => b.Name == "Something");
// You can build up a query by chaining more operataions
// on to it
query = query.Where(b => b.PublishDate < DateTime.Today);
query = query.OrderBy(b => b.Id);
// Your ORM may be able to handle the StartsWith, EndsWith,
// Contains string methods. Check its documentation.
query = query.Where(b => b.Name.StartsWith("The"))
// Since the query object implements IQueryable, it can translate into
// two appropriate SQL queries.
return query.ToPagedList(2, 50);
相关:Returning IEnumerable<T> vs. IQueryable<T>
我的通用存储库中有以下功能。 var list = query.ToPagedList(pageNumber, pageSizeNumber);
public IEnumerable<T> GetPagedListDbContext(string searchFieldName, string searchText, string searchOperator, string sortFieldName, int? page, int? pageSize)
{
int pageSizeNumber = (pageSize ?? 20);
int pageNumber = (page ?? 1);
string sql = string.Empty;
sql = string.Format("Select * From {0} q ", typeof(T).Name);
switch (searchOperator)
{
case "Starts With":
sql += string.Format("Where q.{0} like '{1}%' ", searchFieldName, searchText);
break;
case "Ends With":
sql += string.Format("Where q.{0} like '%{1}' ", searchFieldName, searchText);
break;
case "Contains":
sql += string.Format("Where q.{0} like '%{1}%' ", searchFieldName, searchText);
break;
case "Equal To":
sql += string.Format("Where q.{0} == '{1}' ", searchFieldName, searchText);
break;
case "Not Equal To":
sql += string.Format("Where q.{0} != '{1}' ", searchFieldName, searchText);
break;
}
if (sortFieldName == null)
{
sql += "Order By q.Id ";
}
else
{
sql += string.Format("Order By q.{0} ", sortFieldName);
}
// RepoDbSet is DbSet
DbSqlQuery<T> query = RepoDbSet.SqlQuery(sql);
var list = query.ToPagedList(pageNumber, pageSizeNumber);
return list;
}
- 它 returns 来自 table 的所有记录。 (Sql 追踪如下)
它执行相同的查询两次。
Sql 跟踪 事件 Class 文本数据
RPC:已完成执行 sp_reset_connection
SQL:BatchCompleted Select * 来自图书 q 排序依据 q.Id
RPC:已完成执行 sp_reset_connection
SQL:BatchCompleted Select * 来自图书 q 排序依据 q.Id
跟踪已停止
问题:
为什么在没有 Skip
和 Take
的情况下执行查询(例如 OFFSET 0 ROWS FETCH NEXT 20 ROWS ONLY
)?
为什么要执行两次?
当我检查最后一行 return list
时,它的总计数为 20,而不是 table 中的总行数,并且没有再次访问数据库。查询的怎么样了?
是否可以使用 Linq 执行相同的过程?
在幕后,ToPagedList 将执行两个操作:
获取总记录数(知道有多少页):
query.Count()
获取当前页记录:
query.Skip((pageNumber - 1) * pageSize).Take(pageSize)
这些导致您看到的两个查询。
它将运行你的自定义,串联SQL,在内存中创建一个对象集合,然后对集合执行LINQ to objects .
这是了解 LINQ 的重要一点。如果该集合支持 IQueryable,则该集合将传递一个表达式树,它可以仔细地将其转换为适当的 SQL。
如果它只支持 IEnumerable,那么查询将在内存中的对象集合上进行操作。
显然 DbSqlQuery 没有实现 IQueryable。
而不是串联 SQL,您应该公开底层 table 对象(EntityFramework?Linq2Sql?什么 ORM?)和 运行 您对此的查询:
var books = context.Books; //or whatever
var query = books.Where(b => b.Name == "Something");
// You can build up a query by chaining more operataions
// on to it
query = query.Where(b => b.PublishDate < DateTime.Today);
query = query.OrderBy(b => b.Id);
// Your ORM may be able to handle the StartsWith, EndsWith,
// Contains string methods. Check its documentation.
query = query.Where(b => b.Name.StartsWith("The"))
// Since the query object implements IQueryable, it can translate into
// two appropriate SQL queries.
return query.ToPagedList(2, 50);
相关:Returning IEnumerable<T> vs. IQueryable<T>