这取决于您的存储库类的设置方式。如果您立即执行查询,即如果您的GetAll()
方法返回类似IEnumerable<T>
orIList<T>
的内容,那么是的,这很容易成为性能问题,除非您真的想一次加载所有记录,否则您通常应该避免这种事情。
另一方面,如果您的GetAll()
方法返回一个IQueryable<T>
,那么可能根本没有问题,这取决于您是否信任编写查询的人。返回 anIQueryable<T>
将允许调用者在实际生成 SQL 代码之前进一步细化搜索条件。就性能而言,只有在使用您的代码的开发人员在执行查询之前没有应用任何过滤器时才会出现问题。如果您足够信任他们,可以给他们足够的绳索让他们上吊(并且可能会降低您的数据库性能),那么仅仅返回IQueryable<T>
可能就足够了。
如果您不信任它们,那么正如其他人指出的那样,您可以通过使用Skip()
和Take()
扩展方法来限制查询返回的记录数来实现简单的分页,但请注意,记录可能会漏掉如果人们在您进入下一页之前对数据库进行了更改。使分页与不断变化的数据库无缝工作比很多人想象的要困难得多。
另一种方法是将您的GetAll()
方法替换为需要调用者在返回结果之前应用过滤器的方法:
public IQueryable<T> GetMatching<T>(Expression<Func<T, bool>> filter)
{
// Replace myQuery with Context.Set<T>() or whatever you're using for data access
return myQuery.Where(filter);
}
然后像var results = GetMatching(x => x.Name == "foo");
, 或任何你想做的事情一样使用它。请注意,这可以通过调用轻松绕过GetMatching(x => true)
,但至少它使意图明确。您还可以将其与第一种方法结合起来,对返回的记录数量设置一个固定上限。
不过,我个人的感觉是,所有这些限制查询的方法只是防止糟糕的开发人员接触你的应用程序,如果你的项目中有糟糕的开发人员,他们无论如何都会找到导致问题的方法你试图做什么。所以我的投票是只返回一个IQueryable<T>
并相信它将被负责任地使用。如果人们滥用它,请拿走该方法并为他们提供类似或类似GetAll()
的训练轮方法,其中查询逻辑超出了他们的控制范围。GetRecentPosts(int count)
GetPostsWithTag(string tag, int count)