av激情亚洲男人的天堂国语,日韩欧美精品一中文字幕,无码av一区二区三区无码,国产又色又爽又刺激的a片,国产又色又爽又刺激的a片

LINQtoSQL:如何直接執(zhí)行SQL語句

1、ExecuteQuery方法

創(chuàng)新互聯建站于2013年開始,是專業(yè)互聯網技術服務公司,擁有項目做網站、網站建設網站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元豐滿做網站,已為上家服務,為豐滿各地企業(yè)和個人服務,聯系電話:13518219792

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

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

調試的時候,通過IntelliTrace跟蹤到:

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

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

ExecuteQuery方法還有一個非泛型方法:

 
 
 
 
  1. //   
  2. // 摘要:   
  3. //     直接對數據庫執(zhí)行 SQL 查詢。   
  4. //   
  5. // 參數:   
  6. //   elementType:   
  7. //       

要返回的 System.Collections.Generic.IEnumerable 的類型。使查詢結果中的列與對象中的字段或屬性相匹配的算法如下所示:如果字段或屬性映射到特定列名稱,則結果集中應包含該列名稱。如果未映射字段或屬性,則結果集中應包含其名稱與該字段或屬性相同的列。通過先查找區(qū)分大小寫的匹配來執(zhí)行比較。如果未找到匹配項,則會繼續(xù)搜索不區(qū)分大小寫的匹配項。如果同時滿足下列所有條件,則該查詢應當返回(除延遲加載的對象外的)對象的所有跟蹤的字段和屬性:T

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

看它的參數需要多傳遞一個elementType,明顯不如泛型方法簡潔。

2、ExecuteCommand方法

同樣道理,這個方法立刻讓我們聯想到(世界沒有聯想,生活將會怎樣?),聯想到,等等,不知聯想到什么。然后我們看一下方法使用說明:

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

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

 
 
 
 
  1. ///    
  2. /// 直接執(zhí)行sql語句 根據用戶Id更新體重   
  3. ///    
  4. /// 用戶Id   
  5. /// 更新后的體重   
  6. ///    
  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;   

調試過程中,通過IntelliTrace可以很清楚地捕獲:

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

3、防止sql注入

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

(1)、直接執(zhí)行拼接的sql語句(有風險)

 
 
 
 
  1. ///    
  2. /// 直接執(zhí)行sql語句 根據用戶Id更新FirstName   
  3. ///    
  4. /// 用戶Id   
  5. /// 更新后的FirstName   
  6. ///    
  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. //這么拼接有風險   
  11.  int result = dataContext.ExecuteCommand(strSql);   
  12. Console.WriteLine();   
  13. Console.WriteLine("affect num:{0}", result);   
  14.  return result;   
  15.  } 

然后,在客戶端這樣調用這個方法:

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

運行的時候,直接拋出異常,提示“Anders”附近有語法錯誤。毫無疑問,它執(zhí)行的sql語句:

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

是不能通過的,同時證明了string.format函數不能有效防止sql注入。

(2)、直接通過linq方法的參數傳遞,結果如何呢?

改進(1)的傳參方法:

 
 
 
 
  1. ///    
  2. /// 直接執(zhí)行sql語句 根據用戶Id更新FirstName   
  3. ///    
  4. /// 用戶Id   
  5. /// 更新后的FirstName   
  6. ///    
  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. //這么拼接有風險   
  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;   

再次通過如下的方式調用:

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

這一次運行正常嗎?經測試,真的真的是真的正常,終于可以長松一口氣了。查看數據庫,Id為10的那一條記錄的FirstName結果改變成了“'Anders'”(帶單引號),明白ADO.NET工作原理的都知道這個一點也不神奇,不是嗎?

對比(1)和(2),我們發(fā)現還是用linq2sql的源生方法傳參比較好,通過拼接sql應該盡量避免。

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

4、思考

ADO.NET中比較常用的ExecuteScalar方法,在linq2sql應該怎么實現呢?您嘗試使用過了嗎?

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


本文題目:LINQtoSQL:如何直接執(zhí)行SQL語句
轉載來于:http://uogjgqi.cn/article/djcjjhj.html
掃二維碼與項目經理溝通

我們在微信上24小時期待你的聲音

解答本文疑問/技術咨詢/運營咨詢/技術建議/互聯網交流