日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
詳解LINQtoSQL簡(jiǎn)單的單表批量刪除

今天在網(wǎng)上看到老趙前輩的擴(kuò)展LINQ to SQL:使用Lambda Expression批量刪除數(shù)據(jù),我看完了文章,還沒(méi)有看源代碼,我一般都習(xí)慣于在看別人的代碼前,思考一下如果我來(lái)實(shí)現(xiàn)我會(huì)如何實(shí)現(xiàn)。我想了許久操作表達(dá)式樹(shù)操作二元表達(dá)式(BinaryExpression)我是肯定困難的,對(duì)于表達(dá)式類庫(kù)的了解不多,用了Reflector反射,結(jié)果什么都看不見(jiàn),也許我的Reflector版本低了,沒(méi)有更新。我就放棄了這種實(shí)現(xiàn)方式,我想有沒(méi)有其他的方式呢?最終我覺(jué)得可以操作生成sql執(zhí)行同樣可以達(dá)到目的,也許更簡(jiǎn)單化。

成都創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供滄源網(wǎng)站建設(shè)、滄源做網(wǎng)站、滄源網(wǎng)站設(shè)計(jì)、滄源網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)與制作、滄源企業(yè)網(wǎng)站模板建站服務(wù),十多年滄源做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。

如何獲取SQL呢,LINQ中有db.GetCommand(IQueryable )方法,DBCommand的CommandText就是SQL了,那我們?nèi)绾潍@取IQueryable 呢,我的***感覺(jué)就是where方法。所以就有下面的語(yǔ)句了,IQueryable q = source.Where(query).AsQueryable();     DbCommand cmd = db.GetCommand(q);

現(xiàn)在我們等到了查詢SQL,如何轉(zhuǎn)化為Delete呢,我用了正則表達(dá)式匹配。就得到了下面完全代碼:

 
 
 
 
  1. public static class TableExtension
  2.     {
  3.         /// 
  4.         /// 單表操作批量刪除
  5.         /// 
  6.         /// 
  7.         /// 
  8.         /// 
  9.         /// 
  10. public static int Delete(this System.Data.Linq.Table source, Expression> query)
  11.             where T : class
  12.         {
  13.             if (source == null)
  14.                 throw new ArgumentException("source");
  15.             if (query == null)
  16.                 throw new ArgumentException("query");
  17.             //query = t => true;
  18.             //為空DELETE  FROM [dbo].[test] 全刪除;個(gè)人覺(jué)得為空全刪除,很不人道,所以還是拋異常
  19.             System.Data.Linq.DataContext db = source.Context;
  20.             IQueryable q = source.Where(query).AsQueryable();
  21.             DbCommand cmd = db.GetCommand(q);
  22.             string sql = cmd.CommandText;
  23.             string regex =
  24.  @"from\s*\[\s*dbo\s*\]\s*\.\s*\[\s*\w+\s*\]\s*(?(as\s*(?(\[\s*\w+\s*\]))))(\.|(\r)|(\n))*";
  25. MatchCollection matches = Regex.Matches(sql, regex, RegexOptions.Multiline | RegexOptions.IgnoreCase);
  26.             Debug.Assert(matches != null, "regex match :null");
  27.             Debug.Assert(matches.Count == 1, "regex match length :" + matches.Count);
  28.             if (matches != null && matches.Count > 0)
  29.             {
  30.                 Match match = matches[0];
  31.  sql = ("DELETE  " + match.Value.Replace(match.Groups["tableparam"].Value, "") +
  32.     sql.Substring(match.Index + match.Length)).Replace(match.Groups["tablepname"].Value + ".", " ");
  33.    List dbparams = new List();
  34. foreach (SqlParameter item in cmd.Parameters)
  35.                 {
  36.    SqlParameter p = new SqlParameter(item.ParameterName, item.SqlDbType, item.Size);
  37.                     p.Value = item.Value;
  38.                     dbparams.Add(item.Value);
  39.                 }
  40.                 q = null;
  41.                 cmd = null;
  42.                 matches = null;
  43.     Debug.WriteLine("delete sql :" + sql);
  44.    return db.ExecuteCommand(sql, dbparams.ToArray());
  45.             }
  46.             return 0;
  47.         }
  48. 現(xiàn)在我們可以進(jìn)行批量刪除了,如:

      
     
     
     
    1. DataContext.test.Delete(t => t.id > 0 && t.name.Contains("test")
    2. || new string[] { "12", "34", "45" }.Contains(t.name) 
    3. &&  t.name.Length >1);

    是不是很簡(jiǎn)單:看看Debug輸出的SQL:

    在看一個(gè):

     
     
     
     
    1. DataContext.Orders.Delete(t => !t.EmployeeID1.HasValue);

    這個(gè)擴(kuò)展中的缺點(diǎn):

    1:只針對(duì)對(duì)單表操作,不支持linq的連接,如:DataContext.test.Delete(t => t.Orders.OrderID > 0);我這個(gè)我認(rèn)為這個(gè)可以通過(guò)一個(gè)更復(fù)雜正則表達(dá)式完成。還有一種思路更簡(jiǎn)潔,就是通過(guò)sql server支持的表變量或者是臨時(shí)表先查詢出結(jié)果,在根據(jù)主鍵實(shí)現(xiàn)刪除。也許你會(huì)說(shuō)可以寫(xiě)成存儲(chǔ)過(guò)程,我個(gè)人不喜歡它,我一般盡量在程序中TSQL,移植性好,除非性能考慮采用存儲(chǔ)過(guò)程。

    2:事務(wù)處理:在這里只是一個(gè)先前的測(cè)試Demo,所以么有考慮。我覺(jué)得我們可以建立一個(gè)類來(lái)管理sql語(yǔ)句或者查詢條件表達(dá)式在調(diào)用save方法時(shí)候進(jìn)行內(nèi)部事務(wù)操作(我一般不喜歡將事務(wù)顯示在外部,因?yàn)槲矣X(jué)得事務(wù)很費(fèi)資源,等待時(shí)間過(guò)長(zhǎng)數(shù)據(jù)庫(kù)容易崩潰,或者對(duì)表的鎖定等,不知道這個(gè)想法對(duì)不對(duì),請(qǐng)大家給個(gè)建議)?,F(xiàn)在可以在外部事務(wù)操作就是有點(diǎn)像ADO.NET了,呵呵麻煩。

    優(yōu)點(diǎn):

    1:可以支持復(fù)雜的表達(dá)式,想老趙提到的“item.Introduction.Length < 10“,以及后面評(píng)論中提到的in、like等。

    2:實(shí)現(xiàn)簡(jiǎn)單,操作簡(jiǎn)單,這是最重要的,代碼很容易理解。

    3:執(zhí)行不需要從數(shù)據(jù)庫(kù)里取出實(shí)體在執(zhí)行,這是Linq的做法。更符合我們的習(xí)慣。我看見(jiàn)在老趙博客***一個(gè)評(píng)論說(shuō)它用EF也實(shí)現(xiàn)了批量刪除,它的那種方式是取出實(shí)體在delete,其實(shí)并不是EF特有的,Linq也完全可以實(shí)現(xiàn),就幾行代碼而已。

    還想多寫(xiě)一些優(yōu)點(diǎn),暫時(shí)就想到這些,有什么Bug或者建議請(qǐng)大家一定要指出。還有就是不知道這樣對(duì)內(nèi)存有么有影響,還沒(méi)有來(lái)得及測(cè)試。我個(gè)人覺(jué)得其實(shí)計(jì)算機(jī)的東西都是我們生活中簡(jiǎn)單的問(wèn)題運(yùn)用,就在個(gè)人的思維了,就和前面講的老外Linq組合查詢的PredicateExtensions類一樣。恩現(xiàn)在趕緊去看看老趙前輩的實(shí)現(xiàn)方式了,還沒(méi)來(lái)得及看過(guò)一行代碼呢,不知對(duì)事務(wù)、多表的支持如何。

    鏈接:http://www.cnblogs.com/whitewolf/archive/2010/08/04/1791682.html


    本文名稱:詳解LINQtoSQL簡(jiǎn)單的單表批量刪除
    文章出自:http://m.5511xx.com/article/djhphdo.html