2010-04-09 39 views
2

我的項目結構如下:MVC和存儲庫模式的數據效率

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; 

} 

比方說(5)應該在GetPostFeeds返回5個最新的提要。通過列表,不是從GetPosts()中的數據庫中拉出每一篇文章,只是從中提取5篇文章?

如果每篇文章都說從數據庫5kb,並有100萬條記錄。不是說每次調用GetPostFeeds()時都會使用5GB內存?

這是它發生的方式?我應該回到我的DAL並編寫只返回我需要的查詢嗎?

+0

您應該考慮爲Post提取POCO樣式的接口,以便調用Service層的層不必知道Post類。我猜測Post是一個Linq-to-SQL類,有表映射和東西裝飾?存儲庫模式的好處之一是完全抽象出你的數據實現,如果你的主層必須引用你的數據對象,你就不能這樣做。 – 2010-04-10 01:33:41

回答

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

直到執行ToList()時,才執行延遲執行。那時,是的,整個工具包和堆放物都被拉下來了。

如果您想要更智能的執行,請考慮消除ToList()調用。在整個調用鏈中使用IQueryables將允許您的存儲庫只檢索您需要的五條記錄。

一旦你只有五條記錄你需要,那麼你可以撥打ToList()

+0

因此,如果我刪除ToList(),並在GetPostFeeds函數內,如果我按照日期排序的前5名,它只從數據庫中提取,或者它仍然是一切? – 2010-04-09 22:51:22

+0

是的,這將工作。原理是在你完成一個'.Where()'後將'ToList()'*調用到你需要的五條記錄。調用ToList()將強制立即執行,所以先進行過濾,*調用ToList()之前。 – 2010-04-09 22:52:52

+0

你說我應該從IList更改爲IQueryable裏面的服務嗎? – 2010-04-09 22:53:42

0

同意,利用的IQueryable可以避免返回整個表。如果您不希望IQueryable泄漏出DAL,則可以考慮通過展開合約將take()調用移入DAL,以便DAL公開可接受「top n」參數的方法。