一. 前言
在前面的兩個章節中,我們分別詳細介紹了EF的增刪改的兩種方式(方法和狀態)和EF查詢的兩種方式( Lambda和Linq ),進行到這里,可以說對於EF,已經入門了,本來應該繼續往下進行EF的高級屬性,但本章節要打斷一下,俗話所得好,“做人不能忘本”,應用到開發領域,就是“編碼也不能忘本”,我們原始的SQL語句,在本章節將結合EF的調用,進行復習一番。
本章節我們要達到的目標是:
① 掌握基本的單表和多表SQL操作(單表操作復習和多表操作復習)
② 加深SQL重點關鍵字的使用(去復習)
③ SQL參數化的寫法
④ EF如何調用各類SQL語句
二. 兩大核心方法
1. 從程序集的角度分析
EF調用SQL語句,主要是依賴於DbContext→DataBase類下SqlQuery和ExecuteSqlCommand兩個方法,來處理查詢的SQL語句、增刪改或其它的SQL語句。
2. 封裝思想
結合泛型方法和參數化查詢,將這兩個方法進行簡單封裝一下,方便后面代碼的調用。
1 #region 01-封裝增刪改或其他的方法 2 /// <summary> 3 /// 封裝增刪改或其他的方法 4 /// </summary> 5 /// <param name="db">數據庫連接上下文</param> 6 /// <param name="sql">數據庫sql語句</param> 7 /// <param name="paras">參數化參數</param> 8 /// <returns></returns> 9 public static int ExecuteSqlCommand(DbContext db, string sql, params SqlParameter[] paras) 10 { 11 return db.Database.ExecuteSqlCommand(sql, paras); 12 } 13 #endregion 14 15 #region 02-執行查詢操作(結果為集合) 16 17 public static List<T> SqlQueryList<T>(DbContext db, string sql, params SqlParameter[] paras) 18 { 19 return db.Database.SqlQuery<T>(sql, paras).ToList(); 20 } 21 #endregion 22 23 #region 03-執行查詢操作(結果為單一實體) 24 25 public static T SqlQuery<T>(DbContext db, string sql, params SqlParameter[] paras) 26 { 27 return db.Database.SqlQuery<T>(sql, paras).FirstOrDefault(); 28 } 29 #endregion
補充參數化查詢:
目的:防止SQL注入。 那么什么是SQL注入呢?
SQL 注入漏洞存在的原因,就是拼接 SQL 參數。也就是將用於輸入的查詢參數,直接拼接在 SQL 語句中,導致了SQL 注入漏洞。
舉例:String sql = "select * from user where id=" + id; 該局sql語句的目的是通過id來查詢用戶信息,id的值傳入進入。
SQL注入的寫法:id值傳為: 2 or 1=1 ,由於 1=1 始終為true,加上or的配合,可以將所有的user信息查出來。
以上還是比較溫柔的:下面來個狠的,比如: 2; truncate table user 這種破壞就有點可怕了。
參數化查詢的寫法:
String sql = "select * from user where id=@id" ;
SqlParameter[] paras ={
new SqlParameter("@id","2"), };
這種寫法,就有效的阻止SQL注入的風險。
三. 代碼實踐
下面結合代碼,展示EF調用SQL語句進行查詢、增加、修改、刪除、刪除表所有數據的相關操作。
1 using (DbContext db = new CodeFirstModel()) 2 { 3 //1. 查詢TestInfor表中的所有數據 4 Console.WriteLine("-----------------------------1. 查詢TestInfor表中的所有數據----------------------------------"); 5 string sql1 = @"select * from TestInfor"; 6 List<TestInfor> tList = EFSqlTest.SqlQueryList<TestInfor>(db, sql1); 7 tList.ForEach(t => 8 { 9 Console.WriteLine("id值為{0},txt1值為{1},txt2值為{2}", t.id, t.txt1, t.txt2); 10 }); 11 12 //2. 查詢TestInfor表中ID值為2的數據txt1和txt2 13 Console.WriteLine("-----------------------------2. 查詢TestInfor表中ID值為2的數據----------------------------------"); 14 string sql2 = @"select * from TestInfor where id=@id "; 15 SqlParameter[] paras ={ 16 new SqlParameter("@id","2"), 17 }; 18 TestInfor T2 = EFSqlTest.SqlQuery<TestInfor>(db, sql2, paras); 19 if (T2!=null) 20 { 21 Console.WriteLine("id值為{0},txt1值為{1},txt2值為{2}", T2.id, T2.txt1, T2.txt2); 22 } 23 else 24 { 25 Console.WriteLine("沒有查出符合條件的數據"); 26 } 27 28 29 //3. 增加一條數據 30 Console.WriteLine("-----------------------------3. 增加一條數據----------------------------------"); 31 string sql3 = @"insert into TestInfor values(@id,@txt1,@txt2)"; 32 SqlParameter[] paras3 ={ 33 new SqlParameter("@id",Guid.NewGuid().ToString("N")), 34 new SqlParameter("@txt1","txt1+"+Guid.NewGuid().ToString("N").Substring(1,2)), 35 new SqlParameter("@txt2","txt2+"+Guid.NewGuid().ToString("N").Substring(1,2)) 36 }; 37 int result3 = EFSqlTest.ExecuteSqlCommand(db, sql3, paras3); 38 if (result3 > 0) 39 { 40 Console.WriteLine("增加成功"); 41 } 42 43 //4. 刪除一條數據 44 Console.WriteLine("-----------------------------4. 刪除一條數據----------------------------------"); 45 string sql4 = @"delete from TestInfor where id=@id"; 46 SqlParameter[] paras4 ={ 47 new SqlParameter("@id","1"), 48 }; 49 int result4 = EFSqlTest.ExecuteSqlCommand(db, sql4, paras4); 50 if (result4 > 0) 51 { 52 Console.WriteLine("刪除成功"); 53 } 54 else 55 { 56 Console.WriteLine("沒有查到相應的數據進行刪除"); 57 } 58 59 //5. 修改一條數據 60 Console.WriteLine("-----------------------------5. 修改一條數據----------------------------------"); 61 string sql5 = @"update TestInfor set txt1=@txt1 where id=@id"; 62 SqlParameter[] paras5 ={ 63 new SqlParameter("@id","2"), 64 new SqlParameter("@txt1","limaru") 65 }; 66 int result5 = EFSqlTest.ExecuteSqlCommand(db, sql5, paras5); 67 if (result5 > 0) 68 { 69 Console.WriteLine("修改成功"); 70 } 71 else 72 { 73 Console.WriteLine("沒有查到相應的數據進行修改"); 74 } 75 76 //6. 刪除表中的所有數據 77 Console.WriteLine("-----------------------------6. 刪除表中的所有數據----------------------------------"); 78 string sql6 = @"truncate table LoginRecords"; 79 //執行成功的話 result6仍然為0 80 int result6 = EFSqlTest.ExecuteSqlCommand(db, sql6); 81 82 }
思考:EF執行多條SQL語句,如何控制事務一體呢?
在后續EF事務章節將詳細介紹該問題的解決方案,敬請期待。