我必须编写以下方法的代码:
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#中这样做意味着我必须加载整个产品列表,这也很糟糕......
知道这里最好的选择是什么?我错过了一个选项吗?
答案 0 :(得分:4)
你肯定希望让DB为你做这件事。从数据库中为每个请求移动~250K记录将是一个巨大的开销。如果您使用的是LINQ-to-SQL,Skip
和Take
方法将执行此操作(here is an example),但我不确切知道它们的效率。
答案 1 :(得分:1)
我认为其他(和最好的)选项是使用一些更高级别的框架来保护您免受查询编写的复杂性。 EntityFramework,NHibernate和LINQ(toSQL)可以为您提供很多帮助。在您的情况下,数据库通常是最好的地方。
答案 2 :(得分:1)
今天我自己为我的网站实施分页。虽然我正在使用Entity-Framework,但我已经完成了存储过程。我发现执行复杂查询比获取所有记录和对代码进行分页更好。所以用存储过程来做。 我看到你的代码行,你已经附加了,我只以同样的方式实现。
答案 3 :(得分:1)
我肯定会在存储过程中执行以下操作:
SELECT * FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY Quantity) AS row, *
FROM Products
) AS a WHERE row BETWEEN 11 AND 20
如果您使用的是linq,那么Take和Skip方法将为您解决此问题。
答案 4 :(得分:0)
如果可能的话,肯定在DB中作为首选项。
有时你可以混合一些东西,比如你从数据库函数返回的结果(不是存储过程,函数可以是存储过程不能的大型查询的一部分),那么你可以有另一个函数order和paginate,或者可能有Linq2SQL或类似调用来自所述函数的结果页面,根据需要生成正确的SQL。
如果你至少可以在数据库中完成订购,并且通常只需要前几页(经常在实际使用中发生),那么你至少可以在这些情况下获得合理的性能,因为只有足够的行跳过,然后采取,需要从db加载所需的行。你当然还需要测试那些在某些人真正寻找第1,2312页的罕见情况下性能是否合理!
但是,对于分页确实非常困难的情况,这只是一个折衷方案,因为规则总是在数据库页面,除非由于某种原因要么极其困难,要么总行数保证很低。