[小技巧]EF Core中如何获取上下文中操作过的实体
原文地址:https://www.cnblogs.com/lwqlun/p/10576443.html
作者:Lamond Lu?
源代碼:https://github.com/lamondlu/EFCoreFindSample
背景介紹
當(dāng)我們?cè)诠ぷ鲉卧?UnitOfWork)中使用EF/EF Core的時(shí)候,為了要保持事務(wù),一個(gè)用戶操作只能調(diào)用一次SaveChange方法,但是有時(shí)候一個(gè)用戶操作需要調(diào)用多個(gè)Repository,并且他們操作的實(shí)體是關(guān)聯(lián)的。這時(shí)候在一個(gè)Repository中獲取另外一個(gè)Repository中添加/修改/刪除的實(shí)體就變成了一個(gè)問(wèn)題。
問(wèn)題說(shuō)明
當(dāng)前我們做一個(gè)學(xué)生管理系統(tǒng),學(xué)生和班之間是多對(duì)多關(guān)系,一個(gè)學(xué)生可以屬于多個(gè)班, 因此我們創(chuàng)建了如下的EF上下文。
在用戶界面上,我們?cè)试S用戶在添加學(xué)生的時(shí)候,同時(shí)將學(xué)生分配到一個(gè)班級(jí)中。
因此我們的控制器代碼如下:
為了完成我們的業(yè)務(wù),在StudentManager的AddStudent方法中,我們需要完成兩步操作
?添加學(xué)生信息?將學(xué)生分配給指定班
這里我們使用StudentRepository的AddStudent方法來(lái)完成保存學(xué)生信息,使用GroupRepository的AssignStudentToGroup方法來(lái)將學(xué)生分配給班級(jí)。
這里,其實(shí)不應(yīng)該將保存學(xué)生信息和分配班級(jí)都放在這里,可以使用事件發(fā)布/訂閱[3]將其分配班級(jí)的邏輯移動(dòng)到別處。
針對(duì)保存學(xué)生信息的操作,代碼很簡(jiǎn)單。
但是當(dāng)我們繼續(xù)編寫AssignStudentToGroup方法時(shí)就會(huì)遇到問(wèn)題,我們?cè)撊绾潍@取到前面方法中添加的Student實(shí)體?
這時(shí)候,有同學(xué)會(huì)去嘗試
_dbContext.Students.Where(p=>p.StudentId = studentId)
你會(huì)發(fā)現(xiàn)它獲取不到你想要的對(duì)象,原因是這條語(yǔ)句進(jìn)行的是數(shù)據(jù)庫(kù)查詢,當(dāng)前新增的Student對(duì)象還沒(méi)有保存到數(shù)據(jù)庫(kù)
那么如何解決這個(gè)問(wèn)題呢?這里有2種解決方案
?從ChangeTracker上獲取?使用Find方法獲取
從ChangeTracker上獲取
ChangeTracker是EF/EF Core中的核心對(duì)象,在這個(gè)對(duì)象中記錄了當(dāng)前EF上下文,操作過(guò)的所有實(shí)體,實(shí)體狀態(tài)及實(shí)體屬性的變更。
ChangeTracker中的Entries泛型方法可以幫助我們獲取到當(dāng)前上下文中操作過(guò)的指定類型實(shí)體集合。
但是這樣寫會(huì)出現(xiàn)一個(gè)問(wèn)題,如果我想為一個(gè)數(shù)據(jù)庫(kù)中已經(jīng)存在的學(xué)生分配班級(jí),調(diào)用這個(gè)方法就會(huì)出現(xiàn)問(wèn)題,因?yàn)樵搶?shí)體還未加載到ChangeTracker中, 所以我們這里還需要使用_dbContext.Students.First方法進(jìn)行數(shù)據(jù)庫(kù)查詢.
至此,整個(gè)方法的修改就完成了。如果你覺(jué)著這種方式比較繁瑣,請(qǐng)繼續(xù)看下面的Find方法。
使用Find方法
EF/EF Core中其實(shí)還提供了一個(gè)Find方法,以下是該方法的方法簽名。
從這個(gè)Find方法的注釋中,我們可以了解到,Find方法可以根據(jù)實(shí)體主鍵查詢實(shí)體。但是它的優(yōu)點(diǎn)是,它會(huì)優(yōu)先去ChangeTracker中查找,如果查找不到才會(huì)生成查詢語(yǔ)句,進(jìn)行數(shù)據(jù)庫(kù)查詢。
由此,我們可以使用Find方法修改AssignStudentToGroup方法,看起來(lái)比之前的代碼簡(jiǎn)化了不少
References
[1]:?https://www.cnblogs.com/lwqlun/p/10576443.html
[2]:?https://github.com/lamondlu/EFCoreFindSample
[3]?事件發(fā)布/訂閱:?https://www.cnblogs.com/lwqlun/p/10468058.html
總結(jié)
以上是生活随笔為你收集整理的[小技巧]EF Core中如何获取上下文中操作过的实体的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 如何使用vs将asp.net core项
- 下一篇: IdentityServer4-前后端分