2017-07-31 76 views
4

我有這些領域模型實體框架 - 延遲加載或額外的異步/等待查詢方法?

public class Topic 
{ 
    public int TopicId { get; set; } 

    public virtual ICollection<Post> Posts { get; set; } 
} 

public class Post 
{ 
    public int PostId { get; set; } 

    public int? TopicId { get; set; } 
    public virtual Topic Topic { get; set; } 
} 

比如我想impliment方法TestAsync,還有我想Topic對象和相關文章的對象打交道。

主題模型我可以使用async方法和topicId作爲參數。

public async Task<bool> TestAsync(int topicId) 
{ 
    var topic = await topicService.GetByIdAsync(topicId); 

    // posts ... 
} 

我有兩種方法,如何獲得相關的帖子。 但是,如果我將使用LazyLoading或另一個異步查詢,有什麼區別?

// Example: 1 (LazyLoading) 
var posts = topic.Posts; 

// OR Example: 2 (Async method) 
var posts = await postService.GetAllByTopicIdAsync(topicId); 

所以,我認爲示例:1將同步工作,並且我也失去了異步/等待代碼的所有優點。 但是,例如:2讓我想,這可能是我不知道所有魅力的懶惰加載:) 任何人都可以澄清我應該使用什麼解決方案,爲什麼?謝謝:)

+0

在ASP.NET中用於數據庫訪問的async/await代碼的「優點」非常少。 –

+0

它不是async/await或懶加載imho之間的選擇。這是向數據庫發出兩個查詢(使用延遲加載)或在sql中加入連接(使用Include進行加載加載)之間的選擇。 –

+0

David,但是在許多文章中,async/await建議使用它來處理與數據庫一起工作的方法,因爲此時線程返回到線程池。 Peter,Eager Loading可以是一個解決方案,謝謝! –

回答

6

延遲加載始終是同步的,這是不幸的。例如,EF Core以其異步優先思路,並不支持延遲加載。

其他選項是按Peter的建議做一個連接(加載),它會異步執行單個查詢;或者執行顯式的第二個異步查詢。你會選擇哪一個歸結爲你的模型通常如何使用。

就我個人而言,如果模型總是一起使用,我會選擇進行急切的加載,否則會執行多個異步查詢。我自己並不使用懶加載,儘管沒有任何東西阻止它的工作。

+0

感謝您的廣泛諮詢。它幫助了我。感謝Peter也是:) –

-1

你不應該這樣做。我假設你的GetByIdAsync()是這樣實現的。

public async Task<Topic> GetByIdAsync(int id) 
{ 
     return await context.Topics.FirstAsync(t=>t.Id == id); 
} 

你應該改變它是

public async Task<Topic> GetByIdAsync(int id) 
{ 
     return await context.Topics.Include(t=>t.Posts).FirstAsync(t=>t.Id == id); 
} 
+0

你不能推薦這個,因爲你不知道內部,也許主題包含成千上萬的記錄和帖子很少使用,那麼這個解決方案是最無效的。 – Gusman

+0

或者,也可以向GetByIdAsyc添加一個參數,以請求加載帖子。 –

+0

@Gusman這就是爲什麼我說「假設」。無論如何,主題中的行數如何影響此解決方案?我好奇。 –