|
ORM框架在刪除數(shù)據(jù)方面一直有個(gè)尷尬,那就是無法通過指定條件批量刪除數(shù)據(jù)(當(dāng)然這本不是ORM的問題,只是使用上感覺不方便)。于是對(duì)于一些刪除操作,我們不得不寫SQL語句或者執(zhí)行存儲(chǔ)過程,例如:
ItemDataContext db = new ItemDataContext();db.ExecuteCommand( "DELETE FROM Item WHERE [CreateTime] < {0}", DateTime.UtcNow.AddMonths(-1));
我始終認(rèn)為,在程序里出現(xiàn)直接的SQL語句是一件很丑陋的事情。在我看來,數(shù)據(jù)庫操作應(yīng)該被封裝起來,而對(duì)于應(yīng)用層的開發(fā)人員來說,眼中應(yīng)該只有對(duì)象——退一步的話也可向數(shù)據(jù)庫發(fā)送指令(就是使用存儲(chǔ)過程)。當(dāng)然,這是理想狀態(tài),值得追求,但不可強(qiáng)求。幸運(yùn)的是C# 3.0所擁有的強(qiáng)大特性足以讓我們對(duì)LINQ to SQL的功能進(jìn)行擴(kuò)展。為了更好地進(jìn)行項(xiàng)目開發(fā),以及周五的一次技術(shù)交流,我為L(zhǎng)INQ to SQL擴(kuò)展了批量刪除功能。當(dāng)項(xiàng)目中引用了這個(gè)擴(kuò)展之后,我們就可以使用如下的代碼來實(shí)現(xiàn)上面的功能了:
ItemDataContext db = new ItemDataContext();db.Items.Delete(item => item.CreateTime < DateTime.UtcNow.AddMonths(-1));
當(dāng)然,擴(kuò)展還支持更復(fù)雜的刪除條件,例如:
ItemDataContext db = new ItemDataContext();db.Items.Delete(item => item.CreateTime < DateTime.UtcNow.AddMonths(-1) || item.ViewCount < item.CommentCount && item.UserName != "jeffz");
之前我對(duì)于LINQ to SQL的擴(kuò)展大都基于DataContext,不過很明顯,這次的擴(kuò)展是基于Table<T>的。總的來說,這個(gè)擴(kuò)展比我想象中要簡(jiǎn)單不少。針對(duì)LINQ的擴(kuò)展最麻煩的地方就在于解析表達(dá)式樹(Expression Tree),而這個(gè)擴(kuò)展關(guān)鍵的就是二元表達(dá)式(BinaryExpression),除了這點(diǎn)就沒有太大問題了——當(dāng)然,這也是因?yàn)槲曳艞壛藢?duì)于復(fù)雜表達(dá)式樹的解析,例如現(xiàn)在就不支持“item.Introduction.Length < 10”這種條件,而對(duì)于更完整的解析方式來說,應(yīng)該將其轉(zhuǎn)化為T-SQL中的LEN函數(shù)。
這個(gè)擴(kuò)展的關(guān)鍵在于根據(jù)表達(dá)式樹生成Where Condition,我使用三個(gè)步驟完成這個(gè)擴(kuò)展,大家可以關(guān)注代碼里的相關(guān)實(shí)現(xiàn)(如果需要的話我也可以在以后進(jìn)行說明):
- 使用PartialEvaluator將表達(dá)式中的常量直接計(jì)算出來(例如“3 * 3”表達(dá)式將被替換為“9”),同時(shí)也會(huì)將一些存儲(chǔ)在變量中的值使用常量進(jìn)行替換。
- 使用ConditionBuilder將表達(dá)式中的常量收集起來,并生成帶參數(shù)的Condition表達(dá)式(例如“[CreateTime] < {0} AND [UserName] <> {1}”)。
- 使用DataContext.ExecuteCommand方法執(zhí)行完整的SQL語句。
有了批量刪除的功能,那么還缺點(diǎn)什么呢?那自然就是批量更新的功能了。批量更新的功能比刪除略為復(fù)雜一些,我正在開發(fā)之中。在有了這個(gè)擴(kuò)展之后,我們就可以使用如下的方法進(jìn)行批量更新了:
ItemDataContext db = new ItemDataContext();db.Items.Update( item => new Item { Introduction = item.Title + "Hello World", ViewCount = item.ViewCount + 1, }, // 更新方式 item => item.CommentCount > 100 /* 更新條件*/);
您可以點(diǎn)擊這里下載我對(duì)批量刪除的擴(kuò)展。
it知識(shí)庫:擴(kuò)展LINQ to SQL:使用Lambda Expression批量刪除數(shù)據(jù),轉(zhuǎn)載需保留來源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。