2 回答

TA貢獻(xiàn)1802條經(jīng)驗(yàn) 獲得超6個(gè)贊
當(dāng)直接從數(shù)據(jù)庫(kù)提供 IEnumerable 時(shí),控制器如何工作?
(我假設(shè)你的意思是直接從你的IEnumerable返回一個(gè)未執(zhí)行的)IQueryableDbContext
他們不會(huì),你也不應(yīng)該- 這是因?yàn)槲磮?zhí)行的IQueryable數(shù)據(jù)并不代表已加載的數(shù)據(jù) - 當(dāng)它執(zhí)行時(shí),它只能從打開(kāi)的數(shù)據(jù)庫(kù)連接加載數(shù)據(jù) - 這需要一個(gè)活動(dòng)且有效的DbContext.
...所以如果 被DbContext處置,則IQueryable無(wú)法執(zhí)行。
如果您DbContext在控制器內(nèi)部創(chuàng)建操作并IQueryable在視圖中渲染或在ObjectResponse(對(duì)于 Web API)中返回它,那么它總是會(huì)失?。?/p>
public IActionResult GetPeople()
{
// WARNING: NEVER DO THIS!
using( MyDbContext db = new MyDbContext( GetConnectionString() ) )
{
return this.Ok( db.People.Where( p => p.Name == "John Smith" ) );
// or:
return this.View( model: db.People.Where( p => p.Name == "John Smith" ) );
}
}
請(qǐng)記住,.Ok()andthis.View()不會(huì)觸發(fā)視圖的評(píng)估或向客戶(hù)端發(fā)送對(duì)象響應(yīng) - 相反,它會(huì)導(dǎo)致控制器操作首先結(jié)束,然后將數(shù)據(jù)傳遞到 ASP.NET 管道中的下一步(即視圖) 。請(qǐng)記?。阂晥D在控制器操作完成后執(zhí)行。
如果您使用依賴(lài)注入在控制器中擁有一個(gè)現(xiàn)成的實(shí)例DbContext,那么結(jié)果就不太可預(yù)測(cè):IQueryable在操作方法返回后仍然可以對(duì) 進(jìn)行評(píng)估,因?yàn)镈bContext直到控制器被處置之后才會(huì)被處置,通常是在視圖已呈現(xiàn),但是您仍然不應(yīng)該這樣做,因?yàn)槟鶬Queryable仍然可能會(huì)傳遞到某個(gè)比您的 Controller 類(lèi)的生命周期更長(zhǎng)的進(jìn)程,這會(huì)導(dǎo)致失敗。您還應(yīng)該避免它,因?yàn)橐晥D被設(shè)計(jì)為快速同步渲染 - 外部數(shù)據(jù)庫(kù)或 IO 調(diào)用會(huì)破壞該設(shè)計(jì)。
(無(wú)論如何,您都不應(yīng)該使用實(shí)體框架實(shí)體對(duì)象作為根 ViewModel,但這是另一個(gè)討論)。
如果您總是使用操作async(DbContext例如ToListAsync(),ToDictionaryAsync等 - 因?yàn)樗鼈兎謩e返回 aTask<List<T>>或TaskDictionary<TKey,TValue>>- 這需要一個(gè)await編譯器默認(rèn)情況下會(huì)阻止您在視圖或?qū)ο蠼Y(jié)果中執(zhí)行的操作,則可以避免這種習(xí)慣(您可以await在視圖中使用,但這是不可取的,需要在某處設(shè)置一些設(shè)置)。
簡(jiǎn)而言之,始終這樣做:
public async Task<IActionResult> GetPeople()
{
using( MyDbContext db = new MyDbContext( GetConnectionString() ) )
{
List<Person> list = await db.People
.Where( p => p.Name == "John Smith" )
.ToListAsync();
// WebAPI:
return this.Ok( list ); // returning an evaluated list, loaded into memory. (Make sure Lazy Navigation Properties are disabled too)
// MVC:
PeopleListViewModel vm = new PeopleListViewModel(); // in MVC always use a custom class for root view-models so you're not accepting nor returning Entity Framework entity types directly
vm.List = list;
return this.View( vm );
}
}

TA貢獻(xiàn)1995條經(jīng)驗(yàn) 獲得超2個(gè)贊
您正在返回一個(gè)由 mvc 框架執(zhí)行的任務(wù);
當(dāng)你等待一個(gè)任務(wù)時(shí),你就開(kāi)始(異步)運(yùn)行它,然后獲取結(jié)果并將其交給 mvc 框架;
您將返回一個(gè)由 mvc 框架執(zhí)行的枚舉器。
我會(huì)選擇選項(xiàng)#2,因?yàn)槟_切知道數(shù)據(jù)庫(kù)查詢(xún)何時(shí)執(zhí)行。由于您要返回任務(wù)并正確使用 async 和 wait 關(guān)鍵字,因此框架將盡可能多地保持線程繁忙,從而利用應(yīng)用程序的吞吐量。
- 2 回答
- 0 關(guān)注
- 208 瀏覽
添加回答
舉報(bào)