? ? ? 一個(gè)系統(tǒng)的復(fù)雜度碘赖,往往因?yàn)楸淼姆倍囗?yè)變的越來(lái)越復(fù)雜,維護(hù)、開(kāi)發(fā)等維度都會(huì)變的越來(lái)越廣普泡,越來(lái)越難以理解播掷。這其中就包括數(shù)據(jù)處理方面,同一個(gè)業(yè)務(wù)場(chǎng)景的數(shù)據(jù)保存在不同的表中撼班,就會(huì)出現(xiàn)多表聯(lián)查這種不可避免的情況歧匈,當(dāng)然本身所有數(shù)據(jù)庫(kù)系統(tǒng)都是支持聯(lián)查的,無(wú)論是左聯(lián)查(left join)還是右聯(lián)查(right join)砰嘁,亦或是模糊查尋件炉。但是我們使用的是EF技術(shù),是盡量避免去過(guò)多在數(shù)據(jù)庫(kù)中進(jìn)行操作矮湘,EF本身就是讓我們注重精力在業(yè)務(wù)層面斟冕!所以,EF的聯(lián)查也是一種技能缅阳,我們本節(jié)就重點(diǎn)實(shí)戰(zhàn)EF的聯(lián)查磕蛇,看看看怎么寫(xiě)。在實(shí)戰(zhàn)聯(lián)查之前十办,我們有必要先實(shí)現(xiàn)api的POST實(shí)現(xiàn) 秀撇,向?qū)W生成績(jī)表中添加數(shù)據(jù),將數(shù)據(jù)準(zhǔn)備就續(xù)橘洞,我們?cè)龠M(jìn)行EF的多表查詢(xún)功能實(shí)戰(zhàn)捌袜。所以本節(jié)的重點(diǎn)是API的POST方法實(shí)現(xiàn),為下一節(jié)的EF多表聯(lián)查做好準(zhǔn)備炸枣。
首先我們打開(kāi)我們的SSMS,新建一個(gè)學(xué)生成績(jī)表弄唧,包括各個(gè)學(xué)科的成績(jī)适肠。如下字段,保存為userAchievement表候引,為了學(xué)習(xí)演示方便侯养,建議你所有的列名、數(shù)據(jù)類(lèi)型都與我完全一致澄干!別忘了設(shè)置主鍵逛揩!
打開(kāi)我們的項(xiàng)目,選擇DataProvider項(xiàng)目中的Model.edmx麸俘,雙擊打開(kāi):
在空白處右鍵:選擇"從數(shù)據(jù)庫(kù)更新模型(U)":
依次選擇我們剛才新那家的學(xué)生成績(jī)表:點(diǎn)擊右下角的完成辩稽,等待生成完畢。
?生成完畢后从媚,我們便可以看到新的模型顯示:
?右鍵選中DataProvider 項(xiàng)目,選擇重新生成逞泄!如果不重新生成,你是無(wú)法使用對(duì)應(yīng)的EF模型的!生成后喷众,再去展開(kāi)Model.tt文件各谚,可以看到,已經(jīng)有了對(duì)應(yīng)的模型到千!
至此昌渤,數(shù)據(jù)模型已經(jīng)準(zhǔn)備就續(xù),現(xiàn)在我們實(shí)現(xiàn)一個(gè)POST方法憔四,并且通過(guò)Postman工具調(diào)用此方法膀息,向?qū)W生成績(jī)表中寫(xiě)入數(shù)據(jù)!
關(guān)于postMan,我也給你準(zhǔn)備好了第三方的教程 加矛,你照著學(xué)習(xí)了解安裝即可履婉,它只是一個(gè)接口測(cè)試工具。點(diǎn)擊此處學(xué)習(xí)了解安裝
打開(kāi)我們Webapplication項(xiàng)目斟览,在ApiModel控制器中定義成績(jī)數(shù)據(jù)模型如下:此數(shù)據(jù)模型的目的就是在POST方法中作為接收前端傳過(guò)來(lái)的實(shí)體參數(shù)毁腿。
實(shí)現(xiàn)如下方法,同時(shí)添加事務(wù)處理苛茂,將們的業(yè)務(wù)邏輯寫(xiě)在try語(yǔ)句里面已烤,如果出現(xiàn)問(wèn)題則事務(wù)回滾還原:
這里有必要講解一下:csdnStudyEntities,這是什么東西呢妓羊?我們按住鍵盤(pán)的Ctrl鍵同時(shí)鼠標(biāo)單擊類(lèi)名稱(chēng)胯究,進(jìn)入這個(gè)類(lèi)的定義:
csdnStudyEntities其實(shí)就是我們建立的數(shù)據(jù)庫(kù)!與庫(kù)存在對(duì)應(yīng)關(guān)系躁绸。下面紅枉所示就是對(duì)應(yīng)我們庫(kù)里面的表裕循!明白了吧!
你也許好奇的已經(jīng)看到了我們每個(gè)方法里面都用到了using(){}語(yǔ)句净刮,
using(){}語(yǔ)句方法剥哑,是為了能夠及時(shí)的釋放資源而設(shè)計(jì)的!當(dāng)我們做一些比較占用資源的操作淹父,而且該類(lèi)或者它的父類(lèi)繼承了IDisposable接口株婴,這樣就可以使用using語(yǔ)句,在此范圍的末尾自動(dòng)將對(duì)象釋放暑认,常見(jiàn)的using使用在對(duì)數(shù)據(jù)庫(kù)的操作的時(shí)候困介。
繼續(xù)我們的接口實(shí)現(xiàn)!我們?cè)趖ry語(yǔ)句的內(nèi)部實(shí)現(xiàn)以下邏輯:
至此蘸际,我們的POST方法已經(jīng)寫(xiě)完座哩,下來(lái),我們需要進(jìn)行測(cè)試捡鱼,因?yàn)檫@個(gè)是POST方法八回,區(qū)別于GET方法將所有的參數(shù)以Key=value的形式直接拼寫(xiě)在URL后面酷愧。POST方法的所有的參數(shù)是在HTTP里面的BODY里面放著,是隱藏的缠诅,URL里面不會(huì)出現(xiàn)參數(shù)溶浴,所以,此時(shí)就必須使用POSTMAN這個(gè)測(cè)試工具進(jìn)行測(cè)試了管引。先把我們的API運(yùn)行起來(lái)士败。
在postman中進(jìn)行配置:分別選擇請(qǐng)求方法為POST,URL為https://localhost:44309/api/user/saveUserAchievement
Headers中添加我們此接口要正常響應(yīng)的協(xié)議:Content-Type=application/json褥伴。你輸入時(shí)會(huì)有自動(dòng)提示谅将,正確填寫(xiě)即可。
然后我們切換到body選項(xiàng)卡上:
配置接口參數(shù):
{
"uid":"99D0ACDFE5C24936996F31D6A7C2EF63",
"literature":"98",
"math":"97",
"enlish":"94",
"bios":"96",
"physical":"99",
"history":"99",
"createDate":""
}
這里的uid從哪里來(lái)的呢重慢?打開(kāi)我們的數(shù)據(jù)庫(kù)SSMS饥臂,在我們的庫(kù)上右鍵新建查詢(xún):
給哪個(gè)用戶(hù)寫(xiě)入數(shù)據(jù),就必須是哪個(gè)用戶(hù)的id似踱,明白了吧隅熙,你需要正確填寫(xiě)你查出來(lái)的id,否則核芽,根據(jù)我們的邏輯囚戚,你是無(wú)法正常將數(shù)據(jù)寫(xiě)入數(shù)據(jù)庫(kù)的!
在我們的方法中打一個(gè)斷點(diǎn)轧简,當(dāng)接口調(diào)用的時(shí)候驰坊,我們方便查看請(qǐng)求參數(shù)值:
?上面準(zhǔn)備就續(xù)后,在postman中點(diǎn)擊右邊的send按鈕哮独,調(diào)用接口:
不出意外拳芙,我們的接口斷點(diǎn)會(huì)被命中,你可以看看實(shí)體的值皮璧!將鼠標(biāo)移動(dòng)到參數(shù)名t上态鳖,依次展開(kāi),你便看到了傳輸過(guò)來(lái)的值恶导!如下:
你可以按鍵盤(pán)上的F10一步一步執(zhí)行,直到return.或者你點(diǎn)擊上方的"繼續(xù)"按鈕浸须,直接運(yùn)行完成跳出斷點(diǎn)惨寿。看看postman的返回删窒!
是不是非常完美裂垦,現(xiàn)在我們?nèi)ゲ橐幌挛覀兊某煽?jī)表,看看數(shù)據(jù)肌索!
?OK蕉拢,非常完美,我們已經(jīng)成功的通過(guò)POST方式將數(shù)據(jù)保存到我們的表中,這是何等的順利晕换!順利之余午乓,我們還是需要冷靜的來(lái)想想這些流程有存在的問(wèn)題:
第一個(gè)問(wèn)題:數(shù)據(jù)模型涉嫌重復(fù),新定義的數(shù)據(jù)模型毫無(wú)意義:
難不成我們要向不同表里面插入數(shù)據(jù)闸准,需要定義那么多的數(shù)據(jù)模型嗎益愈?這個(gè)Achievement模型與EF生成的userAchievement何等的相似!夷家!我們能不能直接使用EF生成的userAchievement呢蒸其?答案是可以的!沒(méi)有任何問(wèn)題库快!這里提出這個(gè)問(wèn)題的目的是摸袁,我在實(shí)際項(xiàng)目開(kāi)發(fā)中遇到了太多這樣重復(fù)定義數(shù)據(jù)model的案例,真的是讓人啼笑皆非义屏!哭笑不得靠汁!所以,同學(xué)們湿蛔,你們自己改造一下這個(gè)方法膀曾,使用EF生成的userAchievement,進(jìn)行測(cè)試阳啥,中途出現(xiàn)的問(wèn)題添谊,自我排查解決,好好掌握一下基本的技能察迟。
第二個(gè)問(wèn)題:我們可不可以使用一種動(dòng)態(tài)模型做為輸入?yún)?shù)斩狱?為什么呢?可以將接口業(yè)務(wù)邏輯與EF生成的模型隔離開(kāi)扎瓶!新增加?如下方法:
在新接口處打個(gè)斷點(diǎn)所踊,將saveUserAchievement([FromBody] Achievement t)方法注釋掉,如果你不注釋?zhuān)銓?huì)得到新的報(bào)錯(cuò)概荷!原因是不能同時(shí)出現(xiàn)兩個(gè)POST方法秕岛!保存運(yùn)行代碼:
?打開(kāi)postMan,替換接口API误证,其它所有數(shù)據(jù)不要?jiǎng)蛹萄Γc(diǎn)擊Send按鈕:看到依然運(yùn)行保存成功?
?查一下數(shù)據(jù)庫(kù)表,看一下數(shù)據(jù):成功插入兩條數(shù)據(jù)愈捅。
至此遏考,POST方法教程實(shí)戰(zhàn)完畢。同學(xué)們?nèi)缤R粯永督鳎噙M(jìn)行總結(jié)歸納學(xué)習(xí)灌具。話(huà)鋒一轉(zhuǎn)猿规,但是碧囊!我們發(fā)現(xiàn)漫贞,我們的兩個(gè)POST方法不能共存处渣!不放,你把兩個(gè)POST方法放開(kāi)截歉,然后通過(guò)postman調(diào)用接口胖腾,看看結(jié)果:
它的意思是說(shuō),找到兩個(gè)匹配的接口瘪松,不知道執(zhí)行哪個(gè)了咸作!我們實(shí)際開(kāi)發(fā)中,一個(gè)控制器包括多個(gè)POST方法是非诚溃可能的记罚!那么如何支持多POST方法呢?這個(gè)時(shí)候壳嚎,我們就得調(diào)整路由規(guī)則了桐智!
方案一、修改路由模板烟馅,如下
將其修改為:
運(yùn)行postman,看看結(jié)果:
方案二说庭、將方案一的方案還原為原來(lái)的格式,即刪除掉/{action}郑趁。在控制器中實(shí)現(xiàn)動(dòng)態(tài)路由配置刊驴。更靈活。
運(yùn)行寡润,看看結(jié)果:
至此結(jié)束捆憎。
下一節(jié),我們將進(jìn)行EF的多表聯(lián)查