我正在實施一個作業單元模式(不是我的選擇,我知道它被一些人認為是一種反模式)。我遇到了一個我不完全理解的情況。
我的通用回購建構式:
this.context = context;
this.dbSet = context.Set<T>();
通用方法:
public virtual async Task<IEnumerable<T>> All()
{
return await dbSet.ToListAsync();
}
我使用它:
var languages = await _unitOfWork.Languages.All();
languages = languages.OrderBy(x => x.Order);
如上所示,我需要走一條線,這樣我才能使用 OrderBy,我不明白為什么。
第二個問題是,ToListAsync 假設回傳一個串列,為什么我會得到一個 IENUMARABLE?
uj5u.com熱心網友回復:
第二個問題是,ToListAsync 假設回傳一個串列,為什么我會得到一個 IENUMARABLE?
List是 的實作IEnumerable。檢查“編程到介面”是什么意思?.
如上所示,我需要走一條線才能使用OrderBy,我不知道為什么。
_unitOfWork.Languages.All()回傳 a Task,你應該得到它的解包結果IEnumerable來應用OrderBy它。
為了使這項作業如您所愿,您應該申請OrderBy等待的結果:
(await _unitOfWork.Languages.All()).OrderBy(x => x.Order);
uj5u.com熱心網友回復:
您將它們放在同一行上的困惑似乎在于它如何應用await. 這應該可以正常作業:
var languages = (await _unitOfWork.Languages.All()).OrderBy(x => x.Order);
您需要這樣做,因為您的All函式回傳了一段Task時間OrderBy不是。
此外,您可能一開始就不想呼叫.ToListAsync(),這只是一個SELECT *沒有任何限制或 where 子句,可能不會一直是“世界末日”,但通常會對您的表現極為不利。
至于你的第二個問題,為什么它回傳一個IEnumerable<T>它是因為List<T>實作IEnumerable<T>和你的函式簽名表明它回傳IEnumerable<T>
public virtual async Task<IEnumerable<T>> All()
我強烈建議不要處理,.ToListAsync或者IEnumerable<T>你不要管它,讓它IQueryable<T>對資料庫進行適當的作業。
編輯:在評論中有人問為什么使用IQueryable<T>. 答案是因為利用.Where,.Any()等等......針對IQueryable會發霉對DB的基礎查詢。
例如,假設您要查找具有Idof的單個物體123。如果您.ToListAsync()不做任何其他修改,它會將資料庫中的每一行拉回到記憶體中的程式中,然后迭代每一行以查找該行。
相反,如果您使用IQueryable<T>- 在您應用.FirstOrDefault(e => e.Id == 123)它的點將被應用到資料庫,并且它將像這樣應用SELECT TOP(1) * FROM MyEntity WHERE [Id] = 123- 拉回單行而不是現有的每一行。
EDIT2:請注意,這也適用于投影。這意味著類似.Select(e => new { FullName = e.FirstName " " e.LastName, State = e.Address.State})只會拉那兩列而不是所有列和您包含的任何導航屬性。在 a .ToList()or之后執行此操作.ToListAsync將拉回所有列/物體并迭代它們以創建一組全新的其他物體。這可能會導致兩種方法之間存在巨大的 CPU/記憶體差異。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/324624.html
