MVC EF 執行SQL語句 最近悟出來一個道理,在這兒分享給大家:學歷代表你的過去,能力代表你的現在,學習代表你的將來。 十年河東十年河西,莫欺少年窮 學無止境,精益求精 閑著沒事,看了一篇關於LINQ和SQL對比的文章,網友們也是積極發言,有人說LINQ簡單,維護了程式的可讀性,易用性。有人說: ...
MVC EF 執行SQL語句
最近悟出來一個道理,在這兒分享給大家:學歷代表你的過去,能力代表你的現在,學習代表你的將來。
十年河東十年河西,莫欺少年窮
學無止境,精益求精
閑著沒事,看了一篇關於LINQ和SQL對比的文章,網友們也是積極發言,有人說LINQ簡單,維護了程式的可讀性,易用性。有人說:LINQ的執行本質其實就是SQL,再好的LINQ也需要轉化為SQL後才能和資料庫交互,LINQ效率低。
在此,表達下觀點:本人支持後者,也就是SQL。
那麼,在EF中,我們怎樣執行SQL呢?
在此,先貼出幾張圖,如下:
1、
2、
3、
4、
根據上圖,我們得知,圖一,圖二兩個方法執行返回Int的方法,諸如:Insert操作,Update操作,delete操作。圖三,圖四返回DbRawSqlQuery的方法,諸如:Select操作。
何為DbRawSqlQuery類型?如下:
由此可見DbRawSqlQuery類型繼承自泛型類型。因此,圖三圖四用於執行Select操作的SQL語句。
那麼,我們該怎麼使用呢?
圖一示例
db.Database.ExecuteSqlCommand("delete語句 或 Update語句 或 Insert語句 "); db.Database.ExecuteSqlCommand("delete語句 或 Update語句 或 Insert語句 ",params object[] parameters);
/// <summary> /// 學生Id /// </summary> /// <param name="i"></param> public StudentScore() { using (StudentContext db = new StudentContext()) { int userid = 8; string name = "Jack"; SqlParameter[] paras = new SqlParameter[] { new SqlParameter("@userId",userid), new SqlParameter("@searchName",name) }; db.Database.ExecuteSqlCommand("delete from S where userId=@userId or UserName=@searchName", paras); } }
圖二實際上是執行存儲過程:
public StudentScore() { using (StudentContext db = new StudentContext()) { db.Database.ExecuteSqlCommand(TransactionalBehavior.DoNotEnsureTransaction,"exec ProcName "); } }
圖三、圖四執行查詢操作,如下所示:
public class StudentScore { public IEnumerable<Student> StudentModel { get; set; }// public IEnumerable<Course> CourseModel { get; set; } public IEnumerable<Score> ScoreModel { get; set; } // public List<StudentScoreVM> StudentScoreList = new List<StudentScoreVM>(); public StudentScore() { } /// <summary> /// 學生Id /// </summary> /// <param name="i"></param> public StudentScore(int Id) { using (StudentContext db = new StudentContext()) { //返回StudentScoreVM對象集合 通過這種方式可實現ViewModel特性 StudentScoreList = db.Database.SqlQuery<StudentScoreVM>("select A.StudentScore,B.Name courseName,C.Name stuName,C.Sex,C.StudentAddress,C.StudentNum from dbo.Score A left join dbo.Course B on A.CourseID=B.Id left join dbo.Student C on A.StudentID=C.Id where 1=1 and C.Id=" + Id + "").ToList(); //返回查詢結果的課程名集合 var stringList = db.Database.SqlQuery<string>("select B.Name courseName from dbo.Score A left join dbo.Course B on A.CourseID=B.Id left join dbo.Student C on A.StudentID=C.Id where 1=1 and C.Id=" + Id + "").ToList(); //返回查詢結果的年齡集合 var intList= db.Database.SqlQuery<string>("select A.Age from dbo.Score A left join dbo.Course B on A.CourseID=B.Id left join dbo.Student C on A.StudentID=C.Id where 1=1 and C.Id=" + Id + "").ToList(); } } }
總結如下:
通過 SQL 查詢語句獲取實體對象集
DbSet 類中的 SqlQuery 方法允許你執行一個返回實體對象集的原生 SQL 查詢. 預設情況下, 返回的對象集會被上下文跟蹤; 這可以通過對方法返回的 DbSqlQuery 對象調用 AsNoTracking 方法取消.返回的結果集一般為 DbSet 所對應的類型, 否則即便是其派生類也無法返回. 如果所查詢的表包含了其他實體類型的數據, 那麼所執行的 SQL 語句應該被正確書寫, 保證只返回指定類型實體的數據. 下麵的例子使用 SqlQuery 方法執行了一個 SQL 查詢, 返回一個 Department 類型的實例集.
讓資料庫執行原生的非查詢 SQL 命令
ExecuteSqlCommand 方法有時會被用在 Code First 創建的資料庫的初始化函數中, 用來對資料庫進行一些額外的配置 (例如, 設置索引). 需要註意的是, 上下文對象並不知道執行了 ExecuteSqlCommand 方法後資料庫中的數據有什麼改變, 除非你從資料庫中載入或重新載入實體集.
調用存儲過程
Code First 並不支持對存儲過程的映射. 但是, 你可以通過 ExecuteSqlCommand 或 SqlQuery 方法直接調用存儲過程. 例如: context.Database.ExecuteSqlCommand ("EXECUTE [dbo].[DoSomething]").
譯註: 本文提到的三個方法 (DbSet.SqlQuery, Database.SqlQuery, Database.ExecuteSqlCommand) 都支持參數化查詢, 用法和 string.Format 類似, 但是在查詢執行時會對傳入的參數進行類型轉換. 如: context.Departments.SqlQuery("select * from Department where DepartmentID = {0}", "6"); 該語句執行時, 會將字元串 "6" 轉化為整數然後再代入查詢語句中執行, 可以有效防止 SQL 註入.
防止 SQL 註入攻擊
應用程式經常要從外部獲取輸入 (來自用戶和其他外部代理) , 然後根據這些輸入執行相關操作. 從用戶或外部代理直接或間接獲取的任何信息都可能利用目標程式語言的語法來執行違法操作. 當目標語言是結構化查詢語言 (SQL) 時, 例如 Transact-SQL, 這個操作被稱為 SQL 註入攻擊. 惡意的用戶可以直接在查詢中註入命令執行操作, 刪除資料庫中的一個表, 拒絕提供服務或修改正在執行的操作的性質. 故你應該使用參數化的查詢, 而不是直接將從外部獲取的字元串插入到查詢字元串中.
轉載來源:https://www.cnblogs.com/chenwolong/p/SqlQuery.html