說(shuo)說(shuo)IUnitOfWork~Linq to Sql與EntityFrameworks中的SubmtChanges()發生了什么事
對于(yu)微軟推出的(de)(de)(de)linq to sql和entity frameworks這(zhe)兩(liang)大(da)ORM工(gong)(gong)具,它為(wei)我們的(de)(de)(de)程(cheng)序(xu)開發(fa)(fa)推供的(de)(de)(de)是操(cao)作簡單(dan),程(cheng)序(xu)結構清晰,代(dai)碼量少,但在(zai)性能上,往(wang)往(wang)是開發(fa)(fa)者(zhe)議論的(de)(de)(de)焦點的(de)(de)(de),確實,有時這(zhe)些ORM工(gong)(gong)具的(de)(de)(de)不可控與操(cao)作不透明性廣泛被開發(fa)(fa)者(zhe)所關注(zhu)和注(zhu)意。
說在前:
通過sql profiler進行檢測后,發展LINQ生成的SQL代(dai)碼確實(shi)不是(shi)我們所能接受的,3個操作,明明是(shi)被TransactionScope括起來組成的一個整體,卻(que)向SQL服務器(qi)建立了3個連接池,這是(shi)為(wei)啥?
想在后:
事實上,如(ru)果你(ni)(ni)好好看(kan)(kan)了(le)MSDN,好好分析了(le)自己(ji)寫的(de)(de)(de)(de)代碼及微(wei)軟官方(fang)(fang)的(de)(de)(de)(de)代碼,你(ni)(ni)就(jiu)不(bu)難發現,確(que)實是我們(men)自己(ji)的(de)(de)(de)(de)代碼有(you)些問(wen)題(ti)(ti),在一(yi)個(ge)操(cao)作(zuo)(zuo)中(zhong),(我們(men)稱為(wei)一(yi)個(ge)工作(zuo)(zuo)單元中(zhong)),往(wang)往(wang)我們(men)的(de)(de)(de)(de)submitchages(linq to sql)或者savechanges(ef)的(de)(de)(de)(de)次數(shu)是根據你(ni)(ni)操(cao)作(zuo)(zuo)方(fang)(fang)法(fa)的(de)(de)(de)(de)數(shu)量決定(ding)的(de)(de)(de)(de),這(zhe)被我們(men)稱為(wei)操(cao)作(zuo)(zuo)方(fang)(fang)法(fa)的(de)(de)(de)(de)原子(zi)性或者方(fang)(fang)法(fa)的(de)(de)(de)(de)完整(zheng)性,是,這(zhe)都沒問(wen)題(ti)(ti),一(yi)個(ge)方(fang)(fang)法(fa)完完整(zheng)整(zheng)的(de)(de)(de)(de)干一(yi)件(jian)事,有(you)始(shi)有(you)終,這(zhe)也(ye)是正(zheng)常的(de)(de)(de)(de),但對于ORM工具來說,它不(bu)知道你(ni)(ni)的(de)(de)(de)(de)業務是什(shen)么(me),它也(ye)不(bu)知道你(ni)(ni)的(de)(de)(de)(de)方(fang)(fang)法(fa)是什(shen)么(me),它只認識自己(ji)的(de)(de)(de)(de)提交語(yu)句(ju)(ju)(submtchanges,savechanges),看(kan)(kan)到了(le)它們(men),ORM就(jiu)馬上將LINQ語(yu)句(ju)(ju)翻譯為(wei)SQL,并(bing)建立鏈接,發送(song)語(yu)句(ju)(ju)到SQL服務器,這(zhe)也(ye)是可(ke)以理解的(de)(de)(de)(de)。
有了想法,才有可能改變:
我們(men)從上圖的圖中可以(yi)看到(dao)問題(ti)(ti),業務層(ceng)一(yi)個(ge)(ge)方(fang)法,調用(yong)DAL層(ceng)兩(liang)(liang)個(ge)(ge)獨(du)立的方(fang)法,DAL層(ceng)兩(liang)(liang)個(ge)(ge)方(fang)法使用(yong)LINQ上下(xia)文也(ye)是各自獨(du)立的,所(suo)以(yi),向(xiang)SQL服務器發消息,肯(ken)定也(ye)是各自完成的,這時性能問題(ti)(ti)就(jiu)出來了,優化它(ta)的方(fang)法是將LINQ上下(xia)文通過面(mian)向(xiang)對象的知識(shi),注入(ru)到(dao)DAL層(ceng),使ProductRepository和UserRepository共用(yong)一(yi)個(ge)(ge)LINQ上下(xia)文,這時,它(ta)們(men)由(you)一(yi)個(ge)(ge)上下(xia)文來完成這個(ge)(ge)提交動作,所(suo)產生的SQL鏈接當然也(ye)就(jiu)變成了一(yi)個(ge)(ge),這就(jiu)是UnitOfWork的思想,即工作單元!
OK,看(kan)到上面的(de)(de)圖(tu),我想大家已經明白了(le),我們的(de)(de)優化完成了(le),將多個(ge)LINQ上下(xia)(xia)文和(he)成了(le)一(yi)個(ge),將與(yu)SQL服務(wu)器(qi)建立的(de)(de)鏈接次(ci)數降低到1次(ci),這時很多服務(wu),程序性能問題也(ye)都很好的(de)(de)解決了(le),呵呵,下(xia)(xia)次(ci)我們將會說(shuo)一(yi)下(xia)(xia),如何讓各各repository對(dui)象(xiang)中(zhong)使(shi)用同一(yi)個(ge)上下(xia)(xia)文!
敬請期待!