我的项目结构如下:
DAL
public IQueryable<Post> GetPosts()
{
var posts = from p in context.Post select p;
return posts;
}
服务
public IList<Post> GetPosts()
{
var posts = repository.GetPosts().ToList();
return posts;
}
//Returns a list of the latest feeds, restricted by the count.
public IList<PostFeed> GetPostFeeds(int latestCount)
{
List<Post> post - GetPosts();
//CODE TO CREATE FEEDS HERE
return feeds;
}
让我们说GetPostFeeds(5)应该返回5个最新的feed。从列表上看,是不是从GetPosts()中提取数据库中的每一个帖子,只是从中提取5?
如果每个帖子都是从数据库中说5kb,并且有100万条记录。每次调用GetPostFeeds()时,不会使用5GB内存吗?
这是它发生的方式吗?我应该回到我的DAL并编写仅返回我需要的查询吗?
答案 0 :(得分:3)
只要您使用IQueryable
,就可以延迟查询执行。一旦您调用ToList()
或执行需要获取数据的其他内容(例如,迭代子集合),就会执行查询。
我认为你不需要太担心你的DAL,因为我喜欢让他们保持相当精益。您可以通过重写GetPostFeeds
方法来利用延迟执行,例如:
//Returns a list of the latest feeds, restricted by the count.
public IList<PostFeed> GetPostFeeds(int latestCount)
{
var posts = repository.GetPosts();
// Perform additional filtering here e.g:
posts = posts.Take(5);
return posts.ToList();
}
答案 1 :(得分:1)
在执行ToList()之前,您将执行延迟执行。那时,是的,整个工具包和货架都被拉下来了。
如果您想要更智能的执行,请考虑取消ToList()
来电。在整个调用链中使用IQueryables
将允许您的存储库仅检索您需要的五个记录。
如果您只需要五条记录,则可以拨打ToList()
。
答案 2 :(得分:0)
同意通过利用IQueryable可以避免返回整个表格。如果您不希望IQueryable泄漏出DAL,您可以考虑通过扩展契约将take()调用移入DAL,以便DAL公开一个接受“top n”参数的方法。