我想用Linq对1,000,000条记录进行排序和分页。我不知道我用来获取数据的方式或是否正确,因为网页速度太慢。
这是我的代码:
public HttpResponseMessage GetAllProducts(int page, string SortColumn,string Name = null)
{
const int PageSize = 4;
HttpResponseMessage response = null;
IEnumerable<Product> result = null;
if (string.IsNullOrEmpty(Name))
{
result = db.Products.OrderBy(SortColumn).AsEnumerable();
}
else
{
result = db.Products
.Where(p => p.Name.StartsWith(Name))
.OrderBy(SortColumn).AsEnumerable();
}
int NumberOfPages = result.Count();
var begin = (page - 1) * PageSize;
var data = result.Skip(begin).Take(PageSize).AsEnumerable();
ProductPager myproduct = new ProductPager
{
ProductList = data,
TotalRecords = NumberOfPages
};
response = Request.CreateResponse(HttpStatusCode.OK, myproduct);
return response;
}
答案 0 :(得分:8)
您目前正在将所有100万条记录从数据库中提取到内存中,并将Skip()
和Take()
应用于该集合。这非常昂贵。将您的IEnumerable<Product>
更改为IQueryable<Product>
并删除对.AsEnumerable()
的调用。
这就是我要做的事情:
public HttpResponseMessage GetAllProducts(int page, string sortColumn, string name = null)
{
const int PageSize = 4;
IQueryable<Product> query = db.Products;
if (!string.IsNullOrEmpty(Name))
{
query = query.Where(p => p.Name.StartsWith(name));
}
int numberOfRecords = result.Count();
var begin = (page - 1) * PageSize;
var data = query.OrderBy(sortColumn)
.Skip(begin).Take(PageSize)
.ToList();
ProductPager myproduct = new ProductPager
{
ProductList = data,
TotalRecords = numberOfRecords
};
return Request.CreateResponse(HttpStatusCode.OK, myproduct);
}
实体框架是 LINQ查询提供程序。当您访问db.Products
时,会返回一个实现IQueryable<Product>
和IEnumerable<Product>
的对象。这为您提供了两组LINQ扩展方法,其中许多方法相互重叠(例如Where()
,Skip()
,Take()
,OrderBy()
和Count()
)。
调用与IQueryable<>
相关的方法,将执行以下两项操作之一:
Where()
和OrderBy()
),没有与数据库相关的实际工作:您只需要另一个IQueryable<>
来记录事实上,您想要使用特定参数调用特定的LINQ方法。 Count()
),将发出一个SQL查询,表示您到目前为止已构建的查询,并且您将检索所需的结果。例如,SQL Server实际上会计算必要的记录,只返回一个数字,而不是返回单个记录。另一方面,如果调用与IEnumerable<>
相关的方法,则会生成一个对象(将立即或稍后评估)执行原始查询(为数据库中的所有产品提供)和然后迭代它来做一些事情,比如过滤,跳过,接受,排序和计数。
由于IQueryable<>
更具体而不是IEnumerable<>
,因此通常会调用IQueryable<>
扩展方法,除非您不遗余力地将结果转换为IEnumerable<>
(这是您在代码中所做的)。