2011-03-25 68 views
4

我必須寫的代碼爲以下方法:在哪裏做分頁/過濾?在數據庫或代碼中?

public IEnumerable<Product> GetProducts(int pageNumber, int pageSize, string sortKey, string sortDirection, string locale, string filterKey, string filterValue) 

的方法,將由web UI被使用並且必須支持分頁,排序和過濾。數據庫(SQL Server 2008)擁有約250,000個產品。我的問題如下:我在哪裏實現分頁,排序和過濾邏輯?我應該在T-SQL存儲過程還是C#代碼中執行?

我認爲如果我在T-SQL中執行它會更好,但最終會出現一個非常複雜的查詢。另一方面,在C#中這樣做意味着我必須加載整個產品列表,這也是不好的...

任何想法這裏最好的選擇是什麼?我錯過了一個選項嗎?

回答

4

你肯定會希望讓DB爲你做這個。從數據庫中爲每個請求移動〜250K記錄將是一個巨大的開銷。如果您使用的是LINQ-to-SQL,則SkipTake方法將執行此操作(here is an example),但我不確切知道它們的效率。

1

我認爲其他(和潛在的最好的)選項是使用一些更高級別的框架,以避免查詢寫作的複雜性。 EntityFramework,NHibernate和LINQ(toSQL)可以幫助你很多。這就是說數據庫通常是最適合您的情況。

1

今天本身我爲我的網站實施分頁。儘管我正在使用Entity-Framework,但我已經完成了存儲過程。我發現執行一個複雜的查詢更好,然後獲取所有記錄並使用代碼進行分頁。因此,使用存儲過程。 我看到你的代碼行,你已經附加,我只用相同的方式實現。

1

我會definatly做一個存儲過程的東西沿着線:

SELECT * FROM (
    SELECT 
      ROW_NUMBER() OVER (ORDER BY Quantity) AS row, * 
    FROM Products 
) AS a WHERE row BETWEEN 11 AND 20 

如果你正在使用LINQ則採取和Skip方法將照顧這對你。

0

絕對在數據庫中,如果有可能的話。

有時候你可以混合一些東西,比如如果你有從數據庫函數返回的結果(不是存儲過程,函數可能是存儲過程無法處理的較大查詢的一部分),那麼你可以有另一個函數順序和分頁,或者可能使用Linq2SQL或類似的函數調用所述函數的結果頁面,根據需要生成正確的SQL。

如果您至少可以在數據庫中完成排序,並且通常只需要前幾頁(經常發生在實際使用中),那麼您至少可以在這些情況下具有合理的性能,因爲只有足夠的行跳轉到,然後取,需要的行需要從數據庫加載。您當然仍然需要測試在那些真正尋找第1,2312頁的罕見情況下,性能是否合理!

儘管如此,這只是對分頁非常困難的情況的妥協,因爲除非由於某些原因非常困難,或者總行數保證較低,否則通常在DB中進行頁面切換。