EF中執行sql語句


EF原理

EF 會自動把 Where()、OrderBy()、Select()等這些編譯成“表達式樹(Expression Tree)”,然后會把表達式樹翻譯成 SQL 語句去執行。(編譯原理,AST)因此不是“把數據都取到內存中,然后使用集合的方法進行數據過濾”,因此性能不會低。但是如果這個操作不能被翻譯成 SQL 語句,則或者報錯,或者被放到內存中操作,性能就會非常低

跟蹤EF的查詢Sql語句:

DbContext 有一個 Database 屬性,其中的 Log 屬性,是 Action<String>委托類型,也就是可以指向一個 void A(string s)方法,其中的參數就是執行的 SQL 語句,每次 EF 執行 SQL 語句的時候都會執行 Log。因此就可以知道執行了什么 SQL。


執行原始sql語句

執行非查詢語句,調用 DbContext 的 Database 屬性的 ExecuteSqlCommand 方法,可以通過占位符的方式傳遞參數:

更新語句

ctx.Database.ExecuteSqlCommand("update T_Persons set Name={0},CreateDateTime=GetDate()","zjf");

占位符的方式不是字符串拼接,經過觀察生成的 SQL 語句,發現仍然是參數化查詢,因此不會有 SQL 注入漏洞。

 

查詢語句:

var q1 = ctx.Database.SqlQuery<Item1>("select Name,Count(*) Count from T_Persons where Id>{0} and CreateDateTime<={1} group by Name"

返回值是 DbRawSqlQuery<T> 類型,也是實現了 IEnumerable 接口

 

類似於 ExecuteScalar 的操作比較麻煩:

int c = ctx.Database.SqlQuery<int>("select count(*) from T_Persons").SingleOrDefault();

 

EF中的對象狀態:

 Detached(游離態,脫離態)、Unchanged(未改變)、Added(新增)、Deleted(刪除)、Modified(被修改)。

轉換圖

Add()、Remove()修改對象的狀態。所有狀態之間幾乎都可以通過: Entry(p).State=xxx 的方式 進行強制狀態轉換

 

 EF 優化的一個技巧

如果查詢出來的對象 只是供顯示使用,不會修改、刪除后保存,那么可以使用AsNoTracking()來使得查詢出來的對象是 Detached 狀態,這樣對對象的修改也還是 Detached狀態,EF 不再跟蹤這個對象狀態的改變,能夠提升性能。

var p1 = ctx.Persons.Where(p => p.Name == "rupeng.com").FirstOrDefault();
Console.WriteLine(ctx.Entry(p1).State);

改成:

var p1 = ctx.Persons.AsNoTracking().Where(p => p.Name == "rupeng.com").FirstOrDefault();
Console.WriteLine(ctx.Entry(p1).State);

因為 AsNoTracking()是 DbQuery 類(DbSet 的父類)的方法,所以要先在 DbSet 后調用AsNoTracking()。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM