簡體   English   中英

LINQ中排序1000000條記錄的最佳方法是什么

[英]What is the best way in LINQ to sort 1000000 Records

我想用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;


}

當前,您正在將所有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<>有關的方法將執行以下兩項操作之一:

  1. 對於不需要立即求值的操作(例如Where()OrderBy() ),沒有完成與數據庫有關的實際工作:您只獲得了另一個IQueryable<> ,它記錄了您想要調用特定LINQ的事實。具有特定參數的方法。
  2. 對於需要立即求值的操作(例如Count() ),將發出一個SQL查詢,代表您到目前為止已建立的查詢,您將檢索所需的結果。 例如,SQL Server實際上將計算必要的記錄,並僅返回一個數字,而不是返回單個記錄。

另一方面,如果調用與IEnumerable<>有關的方法,則會生成一個對象,該對象將(立即或稍后進行評估)執行原始查詢(為您提供數據庫中的所有Products),然后對其進行迭代以執行諸如過濾,跳過,獲取,排序和計數之類的操作。

由於IQueryable<>IEnumerable<> 更具體 ,因此通常會調用IQueryable<>擴展方法,除非您不加選擇地將結果轉換為IEnumerable<> (這是您在代碼中所做的事情) 。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM