NewLife.XCode 上手指南(四) 级联操作
一、本節(jié)簡(jiǎn)介
上一節(jié)我們講的是擴(kuò)展屬性,說(shuō)白了就是從Subject中點(diǎn)出Teacher,從Teacher中可以點(diǎn)出Subject的List. 通常在實(shí)際應(yīng)用中,我們刪除了Teacher,那么這個(gè)老師所帶的課程也就沒(méi)有用了,因?yàn)镾ubjcet沒(méi)有任課老師了.所以我們希望,在刪除Teacher的時(shí)候同時(shí)一起刪除的還有那些課程.所以就有了級(jí)聯(lián)操作.
二、邏輯關(guān)系
在演示級(jí)聯(lián)操作之前,我們先理一下關(guān)系,一個(gè)課程對(duì)應(yīng)了一個(gè)老師,而一個(gè)老師可以帶多個(gè)課目, 這樣一來(lái)刪除老師的時(shí)候可以把其下的所有課目給刪掉,但是刪科目的時(shí)候,不可以刪除老師,因?yàn)槠渌颇窟€關(guān)聯(lián)著這個(gè)老師.邏輯關(guān)系理清了,然后我們來(lái)介紹XCode中的級(jí)聯(lián)操作.
三、關(guān)于Delete和OnDelete以及其他的一些說(shuō)明
XCode中我們可以通過(guò)重載OnDelete,Delete,OnUpdate,Update這些方法.
我們來(lái)看看Delete方法吧.在Delete方法進(jìn)行驗(yàn)證過(guò)后調(diào)用了OnDelete方法,也就是說(shuō)OnDelete方法才是正真的數(shù)據(jù)庫(kù)刪除操作.
同時(shí),我們看到了Delete的說(shuō)明,如果實(shí)體沒(méi)有完整信息,那么就無(wú)法通過(guò)擴(kuò)展屬性刪除附屬數(shù)據(jù).
這個(gè)是什么意思呢? 解釋一下,通常我們可能碰到這樣的情況,在一個(gè)列表中,點(diǎn)擊某一列后面的刪除按鈕,這個(gè)時(shí)候我們都是通過(guò)Post參數(shù)的方式來(lái)獲取到需要?jiǎng)h除的那行數(shù)據(jù)的主鍵ID,在程序里我們可能會(huì)這么寫
string strid = Request.QueryString["id"]; int id = -1; if (!int.TryParse(strid, out id)) throw new Exception("非法參數(shù)!"); //第一種方法直接用實(shí)體靜態(tài)方法刪除 Domain.Teacher.Delete(new string[] {Domain.Teacher._.ID}, new object[] {id}); //第二種方法new一個(gè)實(shí)體刪除
Domain.Teacher teacher = new Domain.Teacher() {ID = id};
teacher.Delete();
//第二種方法先查詢,后刪除 Domain.Teacher.FindByID(id).Delete();那么三種方法有什么區(qū)別?
首先第一種,是不推薦這么寫的,這樣寫呢就相當(dāng)于你組了一條SQL, Delete From teacher where id = 1; XCode由于沒(méi)有獲取到實(shí)體什么都幫不了你,更重要的是,XCode不會(huì)幫你刪除和更新Cache中的內(nèi)容,也就是說(shuō)直到下一次Cache過(guò)期前,你刪除的那條數(shù)據(jù),還是存在中Cache,如果別人在查詢的時(shí)候就會(huì)命中Cache,造成數(shù)據(jù)的不統(tǒng)一;
第二種方法,這種方法僅適用于ID為自增主鍵的情況,XCode會(huì)自動(dòng)幫你嘗試級(jí)聯(lián)刪除,但是不能保證所有的級(jí)聯(lián)都能刪除掉,原因我們?cè)诤竺娴呐e例.這里提一下,因?yàn)閷?shí)體除了ID其他所有的屬性都是null;
第三種方法是最推薦的方法,首先對(duì)于一個(gè)曾經(jīng)有性能潔癖的人來(lái)說(shuō),我是不喜歡查詢后刪除的,但是這里大石頭告訴我,這種查詢不會(huì)超過(guò)20ms,這是主鍵查詢啊! 主鍵查詢是最快的了.沒(méi)有什么能比主鍵查詢還快的了,所以這個(gè)性能的損耗可以忽略不記,但是帶來(lái)的優(yōu)勢(shì)卻是級(jí)聯(lián)操作的完整性和Cache的操作的完整性.
四、XCode中如何寫級(jí)聯(lián)操作
首先我們已經(jīng)知道重載OnDelete,OnUpdate即可.所以操作起來(lái)很簡(jiǎn)單.而且本節(jié)我們不用給XCode編寫任何代碼,XCode代碼生成器已經(jīng)幫我們做好了,各位看官可以打開(kāi)Teacher.Biz.cs第54行可以看到已經(jīng)重載了OnDelete了
protected override int OnDelete() { if (Subjects != null) Subjects.Delete(); return base.OnDelete(); }這里對(duì)代碼做一些解說(shuō),同時(shí)也是對(duì)上面第二種方法的進(jìn)一步說(shuō)明,為什么級(jí)聯(lián)操作會(huì)不完整.同時(shí)也是對(duì)上一節(jié)擴(kuò)展屬性的進(jìn)一步鞏固.
if(Subjects != null)
這里的Subjects就是上一節(jié)我們說(shuō)的擴(kuò)展屬性,程序是死的,程序是沒(méi)有思想的,所以他會(huì)去找到這個(gè)Subject屬性,然后進(jìn)入get方法,判斷發(fā)現(xiàn)_Subject確實(shí)是null 而且id>0并且字典里也是不存在相應(yīng)數(shù)據(jù),所以就會(huì)去執(zhí)行FindAllByTeacherID的方法來(lái)填充這個(gè)Subjects,到這個(gè)Get結(jié)束,我們的teacher這個(gè)new出來(lái)的對(duì)象除了id和subjects兩個(gè)屬性不是null外 其他屬性仍然是null,不要以為XCode會(huì)智能的幫你把其他屬性給自動(dòng)獲取,這個(gè)Subjets正好是你get方法寫的巧合,是靠ID來(lái)查找的.
舉個(gè)例子,如果Teacher類中有一個(gè)屬性是OfficeID,這個(gè)OfficeID又關(guān)聯(lián)到另一張表Office,也就是說(shuō)多個(gè)教師在一個(gè)辦公室中,還可以查某個(gè)辦公室有哪些老師,這個(gè)時(shí)候,由于你是new的一個(gè)teacher實(shí)體,并且除了id外其他都是null
所以即使你寫了一個(gè)Office的擴(kuò)展屬性,跑到Get方法里執(zhí)行到_Office = Office.FindAllByOfficeID(OfficeID); 這個(gè)地方的OfficeID是null,要么報(bào)錯(cuò),要么就是查不到.總之你的級(jí)聯(lián)操作就是不完整的.
五、其他的級(jí)聯(lián)操作
雖然上面我們沒(méi)有要自己寫代碼,但是通常我們是要自己來(lái)完善代碼邏輯的,譬如Update的時(shí)候XCode就沒(méi)有幫我們生成代碼,我們只要記住一點(diǎn),重載OnUpdate,并且在最后調(diào)用base.OnUpdate()方法即可.
舉個(gè)實(shí)際應(yīng)用中的例子,可能和級(jí)聯(lián)操作沒(méi)有太大關(guān)系,但是卻是重載OnUpdate和OnDelete有關(guān)的,通常我們一個(gè)用戶會(huì)有個(gè)頭像,數(shù)據(jù)庫(kù)中保存的是頭像的相對(duì)地址,那么如果用戶修改或刪除了呢,關(guān)聯(lián)的頭像不就沒(méi)有用了嗎,如果不刪除物理文件的話,那日積月累下來(lái)磁盤上的垃圾頭像越來(lái)越多,我們不得不去手動(dòng)清理或做其他的處理.
這個(gè)時(shí)候如果在Update或Delete的時(shí)候重載方法,加上你磁盤操作的方法就可以在編輯和刪除的時(shí)候就把那些沒(méi)有用的垃圾頭像給清理掉了.
具體怎么寫?還要我教你?好吧,我就簡(jiǎn)單的寫一下吧,磁盤操作不是本節(jié)的重點(diǎn),你可以在網(wǎng)上找到很多這樣的方法.
寫到這里突然想到,之前項(xiàng)目里碰到的問(wèn)題,delete是好辦,可是update的時(shí)候,各位看官想一想,Teacher.Pic= "xxx" ; Teacher.Update(); 這個(gè)時(shí)候Pic已經(jīng)變了!!!! 我不知道我要去操作磁盤上哪個(gè)文件了...怎么辦...怎么辦...當(dāng)時(shí)樓主的性能潔癖又犯了,就是不愿意查詢數(shù)據(jù)庫(kù)啊,死活不愿意啊.想盡各種辦法,求助大石頭,求助群友,最后得到的結(jié)論是象這樣的update操作又不頻繁!主鍵查詢速度是最快的!性能潔癖! 所以樓主妥協(xié)了,其實(shí)這種主鍵查詢一次數(shù)據(jù)庫(kù)要不了20ms.
在寫查詢的時(shí)候,要自己寫一個(gè)方法,強(qiáng)制從數(shù)據(jù)庫(kù)取數(shù)據(jù),因?yàn)檫@個(gè)時(shí)候Cache里的pic那個(gè)值也已經(jīng)被修改了.
所以這里,就有了樓主項(xiàng)目里的一段代碼
FindByIDFromDb是樓主重寫的一個(gè)方法,目的是避免從Cache中查找數(shù)據(jù),其實(shí)就是把下面這樣的代碼中,if去掉,else及后面的語(yǔ)句去掉,只留FindAll(_.CompanID,CompanyID)這個(gè)方法,就從數(shù)據(jù)庫(kù)下SQL查找了
本節(jié)到此結(jié)束,下一節(jié)我們講一下復(fù)雜查詢,可能會(huì)分2節(jié)來(lái)講,一節(jié)講復(fù)雜查詢?nèi)绾螌?shí)現(xiàn),一節(jié)講一講大石頭引以為豪的萬(wàn)億級(jí) 數(shù)據(jù)量分頁(yè)(樓主就是被這個(gè)性能所吸引過(guò)來(lái)的~~)
萬(wàn)億級(jí)數(shù)據(jù)量分頁(yè) 大石頭說(shuō)這個(gè)有人超越他就請(qǐng)客吃飯的哦~~~
本節(jié)Demo(基本沒(méi)有寫代碼,所以...不過(guò)還是奉上Demo吧)
http://dl.dbank.com/c0672sbtuj
ps:本節(jié)代碼折疊了哦~~~想要的到論壇上搜索"折疊"就能找到
XCode上手指南系列:
NewLife.XCode 上手指南
NewLife.XCode 上手指南(二) 反向工程使用舉例
NewLife.Xcode 上手指南(三) 擴(kuò)展屬性的使用
NewLife論壇地址:
http://www.newlifex.com/
大石頭博客:
http://www.cnblogs.com/nnhy/
NewLife.XCode開(kāi)發(fā)資源目錄
http://www.cnblogs.com/asxinyu/archive/2012/06/02/2532210.html
總結(jié)
以上是生活随笔為你收集整理的NewLife.XCode 上手指南(四) 级联操作的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: mysql中information_sc
- 下一篇: (原创)IconFont(矢量图标字体)