成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

LINQ to SQL:如何直接執(zhí)行SQL語(yǔ)句

開(kāi)發(fā) 后端
我們將談到在LINQ to SQL環(huán)境下,如何直接執(zhí)行SQL語(yǔ)句的方法,并發(fā)布一張調(diào)試圖供大家參考。

1、ExecuteQuery方法

看命名,我們很容易聯(lián)想到ADO.NET里熟悉的Command的ExecuteNonQuery方法,但是VS的智能提示告訴我們這個(gè)方法返回的是一個(gè)泛型集合,應(yīng)該“所思非所得”。下面通過(guò)一個(gè)簡(jiǎn)單方法,驗(yàn)證我們的猜想(數(shù)據(jù)庫(kù)設(shè)計(jì)可以參考這一篇):

  1. /// <summary>   
  2. /// 直接執(zhí)行sql語(yǔ)句,獲取總?cè)藬?shù)   
  3. /// </summary>   
  4. /// <returns></returns>   
  5.  public int GetTotalCount()   
  6. {   
  7.   string strSql = "SELECT COUNT(0) FROM Person(NOLOCK)";   
  8.    var query = dataContext.ExecuteQuery<int>(strSql);   
  9. int result = query.First<int>();   
  10. Console.WriteLine();   
  11. Console.WriteLine("total count:{0}", result);   
  12. return result;   

調(diào)試的時(shí)候,通過(guò)IntelliTrace跟蹤到:

毫無(wú)疑問(wèn),上面的圖片說(shuō)明最初的想法是不正確的,”ADO.NET:執(zhí)行Reader…”云云,讓我們更加堅(jiān)信它實(shí)際執(zhí)行的應(yīng)該是ExecuteReader方法。當(dāng)然最簡(jiǎn)單的方法是直接查看它的方法說(shuō)明:

  1. // 摘要:   
  2. //     直接對(duì)數(shù)據(jù)庫(kù)執(zhí)行 SQL 查詢(xún)并返回對(duì)象。   
  3. //   
  4. // 參數(shù):   
  5. //   query:   
  6. //     要執(zhí)行的 SQL 查詢(xún)。   
  7. //   
  8. //   parameters:   
  9. //     要傳遞給命令的參數(shù)數(shù)組。注意下面的行為:如果數(shù)組中的對(duì)象的數(shù)目小于命令字符串中已標(biāo)識(shí)的最大數(shù),
  10. 則會(huì)引發(fā)異常。如果數(shù)組包含未在命令字符串中引用的對(duì)象,則不會(huì)引發(fā)異常。如果某參數(shù)為   
  11. //     null,則該參數(shù)會(huì)轉(zhuǎn)換為 DBNull.Value。   
  12. //   
  13. // 類(lèi)型參數(shù):   
  14. //   TResult:   
  15. //     返回的集合中的元素的類(lèi)型。   
  16.  //   
  17. // 返回結(jié)果:   
  18. //     由查詢(xún)返回的對(duì)象的集合。   
  19. public IEnumerable<TResult> ExecuteQuery<TResult>(string query, params object[] parameters); 

ExecuteQuery方法還有一個(gè)非泛型方法:

  1. //   
  2. // 摘要:   
  3. //     直接對(duì)數(shù)據(jù)庫(kù)執(zhí)行 SQL 查詢(xún)。   
  4. //   
  5. // 參數(shù):   
  6. //   elementType:   
  7. //       

要返回的 System.Collections.Generic.IEnumerable<T> 的類(lèi)型。使查詢(xún)結(jié)果中的列與對(duì)象中的字段或?qū)傩韵嗥ヅ涞乃惴ㄈ缦滤荆喝绻侄位驅(qū)傩杂成涞教囟忻Q(chēng),則結(jié)果集中應(yīng)包含該列名稱(chēng)。如果未映射字段或?qū)傩裕瑒t結(jié)果集中應(yīng)包含其名稱(chēng)與該字段或?qū)傩韵嗤牧小Mㄟ^(guò)先查找區(qū)分大小寫(xiě)的匹配來(lái)執(zhí)行比較。如果未找到匹配項(xiàng),則會(huì)繼續(xù)搜索不區(qū)分大小寫(xiě)的匹配項(xiàng)。如果同時(shí)滿(mǎn)足下列所有條件,則該查詢(xún)應(yīng)當(dāng)返回(除延遲加載的對(duì)象外的)對(duì)象的所有跟蹤的字段和屬性:T 

  1. //     是由 System.Data.Linq.DataContext 顯式跟蹤的實(shí)體。
  2. System.Data.Linq.DataContext.ObjectTrackingEnabled   
  3. //     為 true。實(shí)體具有主鍵。否則會(huì)引發(fā)異常。   
  4. //   
  5. //   query:   
  6. //     要執(zhí)行的 SQL 查詢(xún)。   
  7. //   
  8. //   parameters:   
  9. //     要傳遞給命令的參數(shù)數(shù)組。注意下面的行為:如果數(shù)組中的對(duì)象的數(shù)目小于命令字符串中已標(biāo)識(shí)的最大數(shù),
  10. 則會(huì)引發(fā)異常。如果數(shù)組包含未在命令字符串中引用的對(duì)象,則不會(huì)引發(fā)異常。如果某參數(shù)為   
  11. //     null,則該參數(shù)會(huì)轉(zhuǎn)換為 DBNull.Value。   
  12. //   
  13. // 返回結(jié)果:   
  14. //     由查詢(xún)返回的對(duì)象的 System.Collections.Generic.IEnumerable<T> 集合。   
  15. public IEnumerable ExecuteQuery(Type elementType, string query, params object[] parameters);  
  16.  

看它的參數(shù)需要多傳遞一個(gè)elementType,明顯不如泛型方法簡(jiǎn)潔。

2、ExecuteCommand方法

同樣道理,這個(gè)方法立刻讓我們聯(lián)想到(世界沒(méi)有聯(lián)想,生活將會(huì)怎樣?),聯(lián)想到,等等,不知聯(lián)想到什么。然后我們看一下方法使用說(shuō)明:

  1. //   
  2. // 摘要:   
  3. //     直接對(duì)數(shù)據(jù)庫(kù)執(zhí)行 SQL 命令。   
  4. //   
  5. // 參數(shù):   
  6. //   command:   
  7. //     要執(zhí)行的 SQL 命令。   
  8. //   
  9. //   parameters:   
  10. //     要傳遞給命令的參數(shù)數(shù)組。注意下面的行為:如果數(shù)組中的對(duì)象的數(shù)目小于命令字符串中已標(biāo)識(shí)的最大數(shù),
  11. 則會(huì)引發(fā)異常。如果數(shù)組包含未在命令字符串中引用的對(duì)象,則不會(huì)引發(fā)異常。如果任一參數(shù)為   
  12. //     null,則該參數(shù)會(huì)轉(zhuǎn)換為 DBNull.Value。   
  13. //   
  14. // 返回結(jié)果:   
  15. //     一個(gè) int,表示所執(zhí)行命令修改的行數(shù)。   
  16. public int ExecuteCommand(string command, params object[] parameters); 

到這里,看它的返回類(lèi)型為int,表示執(zhí)行命令修改的行數(shù),這次很容易想到ExecuteNonQuery方法。對(duì)不對(duì)呢?通過(guò)下面的代碼證明我們的設(shè)想:

  1. /// <summary>   
  2. /// 直接執(zhí)行sql語(yǔ)句 根據(jù)用戶(hù)Id更新體重   
  3. /// </summary>   
  4. /// <param name="id">用戶(hù)Id</param>   
  5. /// <param name="destWeight">更新后的體重</param>   
  6. /// <returns></returns>   
  7. public int ModifyWeightById(int id, double destWeight)   
  8. {   
  9.   string strSql = string.Format("UPDATE Person SET Weight={0} WHERE Id={1}", destWeight, id);   
  10.  int result = dataContext.ExecuteCommand(strSql);   
  11.  Console.WriteLine();   
  12. Console.WriteLine("affect num:{0}", result);   
  13. return result;   

調(diào)試過(guò)程中,通過(guò)IntelliTrace可以很清楚地捕獲:

“ADO.NET:執(zhí)行NonQuery…”基本可以斷言我們的設(shè)想是正確的。

3、防止sql注入

1和2中,執(zhí)行sql語(yǔ)句的兩個(gè)方法都有一個(gè)params 類(lèi)型的參數(shù),我們又會(huì)想到ADO.NET非常重要的sql語(yǔ)句的參數(shù)化防止sql注入問(wèn)題。下面通過(guò)一個(gè)方法,看看linq2sql可不可以防止sql注入。

(1)、直接執(zhí)行拼接的sql語(yǔ)句(有風(fēng)險(xiǎn))

  1. /// <summary>   
  2. /// 直接執(zhí)行sql語(yǔ)句 根據(jù)用戶(hù)Id更新FirstName   
  3. /// </summary>   
  4. /// <param name="id">用戶(hù)Id</param>   
  5. /// <param name="destName">更新后的FirstName</param>   
  6. /// <returns></returns>   
  7. public int ModifyNameById(int id, string destName)   
  8. {   
  9. string strSql = string.Format("UPDATE Person SET FirstName='{0}' WHERE Id={1}", destName, id);
  10. //這么拼接有風(fēng)險(xiǎn)   
  11.  int result = dataContext.ExecuteCommand(strSql);   
  12. Console.WriteLine();   
  13. Console.WriteLine("affect num:{0}", result);   
  14.  return result;   
  15.  } 

然后,在客戶(hù)端這樣調(diào)用這個(gè)方法:

  1. int result = ServiceFactory.CreatePersonService().ModifyNameById(10, "'Anders'");
  2. //更新id為10的人的FirstName 

 

運(yùn)行的時(shí)候,直接拋出異常,提示“Anders”附近有語(yǔ)法錯(cuò)誤。毫無(wú)疑問(wèn),它執(zhí)行的sql語(yǔ)句:

  1. UPDATE Person SET FirstName=''Anders'' WHERE Id=10 

是不能通過(guò)的,同時(shí)證明了string.format函數(shù)不能有效防止sql注入。

(2)、直接通過(guò)linq方法的參數(shù)傳遞,結(jié)果如何呢?

改進(jìn)(1)的傳參方法:

  1. /// <summary>   
  2. /// 直接執(zhí)行sql語(yǔ)句 根據(jù)用戶(hù)Id更新FirstName   
  3. /// </summary>   
  4. /// <param name="id">用戶(hù)Id</param>   
  5. /// <param name="destName">更新后的FirstName</param>   
  6. /// <returns></returns>   
  7. public int ModifyNameById(int id, string destName)   
  8.  {   
  9. //string strSql = string.Format("UPDATE Person SET FirstName='{0}' WHERE Id={1}", destName, id);
  10. //這么拼接有風(fēng)險(xiǎn)   
  11. //int result = dataContext.ExecuteCommand(strSql);   
  12.  string strSql = "UPDATE Person SET FirstName={0} WHERE Id={1}";   
  13. int result = dataContext.ExecuteCommand(strSql, new object[] { destName, id });   
  14. Console.WriteLine();   
  15.  Console.WriteLine("affect num:{0}", result);   
  16.  return result;   

再次通過(guò)如下的方式調(diào)用:

  1. int result = ServiceFactory.CreatePersonService().ModifyNameById(10, "'Anders'");
  2. //更新id為10的人的FirstName 

這一次運(yùn)行正常嗎?經(jīng)測(cè)試,真的真的是真的正常,終于可以長(zhǎng)松一口氣了。查看數(shù)據(jù)庫(kù),Id為10的那一條記錄的FirstName結(jié)果改變成了“'Anders'”(帶單引號(hào)),明白ADO.NET工作原理的都知道這個(gè)一點(diǎn)也不神奇,不是嗎?

對(duì)比(1)和(2),我們發(fā)現(xiàn)還是用linq2sql的源生方法傳參比較好,通過(guò)拼接sql應(yīng)該盡量避免。

到這里,可能你會(huì)認(rèn)為上面1、2、3全是廢話(huà),知道怎么用不就行了嘛?!其實(shí)很長(zhǎng)一部分時(shí)間我也是這么想這么做的。工作久了,早就習(xí)慣了不求甚解,現(xiàn)在看書(shū),看園子里高手的博客,多多少少會(huì)有點(diǎn)反思。

4、思考

ADO.NET中比較常用的ExecuteScalar方法,在linq2sql應(yīng)該怎么實(shí)現(xiàn)呢?您嘗試使用過(guò)了嗎?

原文鏈接:http://www.cnblogs.com/jeffwongishandsome/archive/2010/11/03/1868438.html

【編輯推薦】

  1. Linq匿名類(lèi)型簡(jiǎn)單概述
  2. Linq隨機(jī)讀取數(shù)據(jù)淺析
  3. Linq Lambda表達(dá)式全面分析
  4. Linq擴(kuò)展方法簡(jiǎn)單分析
  5. 初探Linq局部變量類(lèi)型
責(zé)任編輯:彭凡 來(lái)源: 博客園
相關(guān)推薦

2009-09-07 16:25:14

Linq To SQL

2009-09-10 10:37:15

LINQ to SQL

2009-09-09 18:03:47

LINQ to SQL

2009-09-10 18:02:23

LINQ to SQL

2010-09-25 16:21:41

SQL語(yǔ)句

2009-09-16 17:44:54

LINQ to SQL

2010-09-06 11:24:32

SQL Server語(yǔ)句

2009-09-08 14:45:24

Linq to SQL支持SQL Serve

2010-09-06 13:17:19

SQL Server語(yǔ)句

2013-10-29 16:27:23

MySQLSQL語(yǔ)句

2009-09-18 14:33:37

LINQ to SQLSQL命令

2009-09-07 17:09:45

Linq To Sql

2009-09-08 13:07:15

介紹Linq to S

2009-09-15 10:46:04

LINQ to SQL

2009-09-16 09:38:27

LINQ To SQL

2009-09-18 13:23:27

Northwind對(duì)象LINQ to SQL

2009-09-18 16:41:46

Linq to sql

2009-09-11 09:41:19

LINQ to SQL

2009-09-16 17:11:35

LINQ To SQL

2024-12-26 08:16:26

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 中文字幕在线看 | 久久亚洲高清 | 久久草在线视频 | 国产成人精品一区二区三区视频 | 日韩久久久久久 | 一区二区三区免费在线观看 | 81精品国产乱码久久久久久 | 成人免费区一区二区三区 | 国产亚洲精品久久情网 | 成年人视频免费在线观看 | 亚洲视频在线看 | 911网站大全在线观看 | 在线看一区二区三区 | 亚洲第一中文字幕 | 久久一热| 国产精品一二区 | 在线观看亚洲精品视频 | 国产欧美精品一区二区三区 | 女人夜夜春 | 欧美精品一区久久 | 国产农村一级片 | 久久国产精品久久久久久 | 欧美高清hd | 国产毛片毛片 | 国产乱码精品1区2区3区 | 在线观看视频一区二区三区 | 亚洲免费片 | 一区二区国产精品 | 欧美一区二区三区在线观看视频 | 国产大片一区 | 国产精品久久久久久久久免费樱桃 | 91深夜福利视频 | 国产丝袜av | 91av在线免费播放 | 99在线免费视频 | 性高湖久久久久久久久3小时 | 另类专区成人 | 国内精品伊人久久久久网站 | 欧美视频免费在线观看 | 久久久久av| 日本不卡免费新一二三区 |