溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

LINQ to SQL簡(jiǎn)單的單表批量刪除怎么實(shí)現(xiàn)

發(fā)布時(shí)間:2021-12-01 15:57:07 來源:億速云 閱讀:218 作者:iii 欄目:編程語言

這篇文章主要講解了“LINQ to SQL簡(jiǎn)單的單表批量刪除怎么實(shí)現(xiàn)”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“LINQ to SQL簡(jiǎn)單的單表批量刪除怎么實(shí)現(xiàn)”吧!

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

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

public static class TableExtension      {          /// <summary>          /// 單表操作批量刪除          /// </summary>          /// <typeparam name="T"></typeparam>          /// <param name="source"></param>          /// <param name="query"></param>          /// <returns></returns>  public static int Delete<T>(this System.Data.Linq.Table<T> source, Expression<Func<T, bool>> query)              where T : class         {              if (source == null)                  throw new ArgumentException("source");              if (query == null)                  throw new ArgumentException("query");              //query = t => true;              //為空DELETE  FROM [dbo].[test] 全刪除;個(gè)人覺得為空全刪除,很不人道,所以還是拋異常              System.Data.Linq.DataContext db = source.Context;              IQueryable q = source.Where(query).AsQueryable();              DbCommand cmd = db.GetCommand(q);              string sql = cmd.CommandText;              string regex =   @"from\s*\[\s*dbo\s*\]\s*\.\s*\[\s*\w+\s*\]\s*(?<tableparam>(as\s*(?<tablepname>(\[\s*\w+\s*\]))))(\.|(\r)|(\n))*";  MatchCollection matches = Regex.Matches(sql, regex, RegexOptions.Multiline | RegexOptions.IgnoreCase);              Debug.Assert(matches != null, "regex match :null");              Debug.Assert(matches.Count == 1, "regex match length :" + matches.Count);              if (matches != null && matches.Count > 0)              {                  Match match = matches[0];   sql = ("DELETE  " + match.Value.Replace(match.Groups["tableparam"].Value, "") +      sql.Substring(match.Index + match.Length)).Replace(match.Groups["tablepname"].Value + ".", " ");     List<object> dbparams = new List<object>();  foreach (SqlParameter item in cmd.Parameters)                  {     SqlParameter p = new SqlParameter(item.ParameterName, item.SqlDbType, item.Size);                      p.Value = item.Value;                      dbparams.Add(item.Value);                  }                  q = null;                  cmd = null;                  matches = null;      Debug.WriteLine("delete sql :" + sql);     return db.ExecuteCommand(sql, dbparams.ToArray());                }              return 0;          }

現(xiàn)在我們可以進(jìn)行批量刪除了,如:

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

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

LINQ to SQL簡(jiǎn)單的單表批量刪除怎么實(shí)現(xiàn)

在看一個(gè):

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

LINQ to SQL簡(jiǎn)單的單表批量刪除怎么實(shí)現(xiàn)

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

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

2:事務(wù)處理:在這里只是一個(gè)先前的測(cè)試Demo,所以么有考慮。我覺得我們可以建立一個(gè)類來管理sql語句或者查詢條件表達(dá)式在調(diào)用save方法時(shí)候進(jìn)行內(nèi)部事務(wù)操作(我一般不喜歡將事務(wù)顯示在外部,因?yàn)槲矣X得事務(wù)很費(fèi)資源,等待時(shí)間過長(zhǎng)數(shù)據(jù)庫容易崩潰,或者對(duì)表的鎖定等,不知道這個(gè)想法對(duì)不對(duì),請(qǐng)大家給個(gè)建議)。現(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ù)庫里取出實(shí)體在執(zhí)行,這是Linq的做法。更符合我們的習(xí)慣。我看見在老趙博客***一個(gè)評(píng)論說它用EF也實(shí)現(xiàn)了批量刪除,它的那種方式是取出實(shí)體在delete,其實(shí)并不是EF特有的,Linq也完全可以實(shí)現(xiàn),就幾行代碼而已。

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

感謝各位的閱讀,以上就是“LINQ to SQL簡(jiǎn)單的單表批量刪除怎么實(shí)現(xiàn)”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)LINQ to SQL簡(jiǎn)單的單表批量刪除怎么實(shí)現(xiàn)這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI