[英]How to get records in order from database materialized view using entity framework
首先,我創建了數據庫視圖,我在其中訂購了記錄。 但是當我嘗試執行“Skip”和“Take”時,它們沒有被訂購。
var query = dbContext.UserView.OrderBy(x => x.Id);
for (int i = 0; i < 10; i++)
{
var users = await query
.Skip(i)
.Take(1)
.ToListAsync();
await SendMessage(users);
}
我正在嘗試按塊獲取和發送記錄,但我不想在 memory 中加載它們。
如果我不訂購var query = dbContext.UserView.OrderBy(x => x.Id);
在這里,即使我使用“order by”創建數據庫視圖,我每次在 for 循環中都會收到不同的順序。
當我調用 ToListAsync() 時,它每次都會排序並成為一個較慢的查詢。
有沒有辦法創建數據庫視圖,每次我要求記錄保持相同的順序?
謝謝
數據庫視圖從不按定義排序。 如果存在 ORDER BY 子句,則視圖的 CREATE 或 ALTER 語句將失敗。 不過,在這種情況下,您可以使用來自 dbContext 的.OrderBy()
調用來覆蓋它。
此外,通常最好避免在需要之前調用ToList()
或ToListAysnc()
,在這種情況下,您可能不需要。
至於排序......這就是async
代碼的用途:它讓你在做一件事的同時還在await
另一件事。 結果是事情並不總是按照您預期的順序運行。 但是我們可以做一些事情來提供幫助。
最后,循環的結構方式會向數據庫發送 10 個單獨的查詢。 那很糟。 事實上,它可能是奇怪排序的主要來源,因為其他異步操作應該幾乎立即完成,因此避免了大多數重新排序問題。
你希望它看起來更像這樣:
var query = dbContext.UserView.OrderBy(x => x.Id).Take(10);
foreach(var user in query)
{
await SendMessage(user);
}
如果SendMessge()
只能接受一個序列:
var query = dbContext.UserView.OrderBy(x => x.Id).Take(10);
await SendMessage(query);
如果(且僅當!) SendMessage()
絕對需要一個列表(並且考慮到評論的要求仍然只有一個項目在內存中),我們仍然可以通過僅運行一個查詢來提高性能:
var query = await dbContext.UserView.OrderBy(x => x.Id).Take(10);
foreach(var user in query)
{
//guessing at the type name here)
var list = new List<User>() {user} ;
await SendMessage(list);
}
同樣:上面只在數據庫上運行一個查詢,但一次仍然只有 memory 中的一個項目。
但在最后一種情況下,我可能會首先探索是否也可以更改或重載SendMessage()
以允許IEnumerable<User>
。 也就是說,該方法可能看起來像這樣:
public static async void SendMessage(List<User> users)
{
foreach(var user in users)
{
//send the message
}
}
如果是這樣,您可以這樣更改它:
public static async void SendMessage(IEnumerable<User> users)
{
foreach(var user in users)
{
//send the message
}
}
注意方法中的代碼沒有改變……只有 function 簽名。 最重要的是,您仍然可以在調用方法時將列表傳遞給該方法。 現在您還可以傳遞任何其他可枚舉值,包括此答案中第二個代碼示例的版本。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.