在 EF Core 中實作存盤庫的正確方法是什么?
public IAsyncEnumerable<Order> GetOrder(int orderId)
{
return blablabla.AsAsyncEnumerable();
}
或者
public Task<IEnumerable<Order>> GetOrder(int orderId)
{
return blablabla.ToListAsync();
}
呼叫性能明智AsAsyncEnumerable()嗎?這種方法安全嗎?一方面它不會創建List<T>物件,所以它應該稍微快一點。但是從訂單方面來看,查詢并未具體化,因此我們推遲 SQL 執行,同時結果可能會發生變化。
uj5u.com熱心網友回復:
根據訊息來源, 無論如何.ToListAsync都會在IAsyncEnumerable內部使用,因此在其中一個或另一個中沒有太多的性能優勢。但.ToListAsyncor 的一個重要特征.ToArrayAsync是取消。
public static async Task<List<TSource>> ToListAsync<TSource>(
this IQueryable<TSource> source,
CancellationToken cancellationToken = default)
{
var list = new List<TSource>();
await foreach (var element in source.AsAsyncEnumerable().WithCancellation(cancellationToken))
{
list.Add(element);
}
return list;
}
串列基本上將所有內容保存在記憶體中,但只有當串列非常大時,它才可能是一個嚴重的性能問題。在這種情況下,您可能會考慮分頁您的大回應。
public Task<List<Order>> GetOrders(int orderId, int offset, int limit)
{
return blablabla.Skip(offset).Take(limit).ToListAsync();
}
uj5u.com熱心網友回復:
決定實際上取決于您是希望緩沖還是流式傳輸。
如果要緩沖結果,請使用ToList()或ToListAsync()。
如果要流式傳輸結果,請使用AsEnumerable()或AsAsyncEnumerable()。
從檔案:
緩沖是指將所有查詢結果加載到記憶體中,而流意味著 EF 每次都將一個結果交給應用程式,而不會在記憶體中包含整個結果集。原則上,流式查詢的記憶體需求是固定的——無論查詢回傳 1 行還是 1000 行,它們都是相同的;另一方面,緩沖查詢需要更多記憶體,回傳的行越多。對于產生大型結果集的查詢,這可能是一個重要的性能因素。
一般來說,最好是流式傳輸,除非您需要緩沖。
當您流式傳輸時,一旦讀取了資料,您將無法再次讀取而不再次訪問資料庫。因此,如果您需要多次讀取相同的資料,則需要進行緩沖。
如果存盤庫流式傳輸 a IEnumerable,則呼叫者可以選擇通過呼叫ToList()(或ToListAsync()on IAsyncEnumerable)來緩沖它。如果存盤庫選擇回傳 IList,我們將失去這種靈活性。
所以要回答你的問題,你最好到存盤庫流結果。讓呼叫者決定是否要緩沖。
如果從事該專案的團隊對流語意不滿意,或者如果大多數代碼已經緩沖,則將流的方法后綴為AsStream(例如GetOrdersAsStream())可能是有意義的,以便他們知道他們不應該列舉它不止一次。
因此,存盤庫可以具有:
async Task<List<Order>> GetOrders() => await GetOrdersAsStream.ToListAsync();
IAsyncEnumerable<Order> GetOrdersAsStream() => ...
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/341470.html
