一、原理:
如何查看真正執行的SQL是怎樣的?
DbContext有一個Database屬性,Database屬性有一個Log屬性,是Action委托類型其中的參數就是sql語句,每次EF執行sql語句的時候都會執行Log,因此就知道執行了什么sql;
EF的查詢是“延遲執行”的,只有遍歷結果集的時候才執行select查詢,Tolist()內部也是遍歷結果集形成的List;
static void Main(string[] args) { using (TestDbContext ctx = new TestDbContext()) { ctx.Database.Log = sql => { Console.WriteLine(sql); }; var ps= ctx.Persons.Where(p => p.Id <4); Console.WriteLine("開始執行了"); foreach (var p in ps) { Console.WriteLine(p.ToString()); } Console.ReadKey(); } }
long[] ids = { 2, 5, 8 }; var result = ctx.Persons.Where(p => ids.Contains(p.Id));
result.toList();
//二次過濾,在sql中自動拼接。 long[] ids = { 2, 5, 8 }; var result = ctx.Persons.Where(p => ids.Contains(p.Id)); result = result.Where(p => p.Name.Length > 5);
EF多次指定where來實現動態的復合檢索; select返回值必須寫成IQueryable<Person>
EF是誇數據庫的,如果遷移到Mysql數據庫上,就會編譯成Mysql語法。要配置對應數據庫的EntityFrameworkProvider
每次執行_MigrationHistory 是DBMigration用的,也就是EF幫我們建數據庫,可以禁用:
Database.SetInitializer<****DbContext>(null)
二、執行原始Sql語句:
在一些特殊的場合,需要執行原生的SQL。
執行非查詢語句:調用DbContext 的Database 屬性的ExecutesqlCommand 方法,可以通過占位符的方式傳遞參數:
using (TestDbContext ctx = new TestDbContext()) { string name = "Tony"; ctx.Database.ExecuteSqlCommand("insert into T_Persons(Name,CreateDateTime) values({0},GetDate())", name); Console.ReadKey(); }
執行查詢語句:
static void Main(string[] args) { using (TestDbContext ctx = new TestDbContext()) { var result= ctx.Database.SqlQuery<GroupCount>(" select Age,COUNT(*) as GroupCounts from T_Persons group by Age "); foreach (var item in result) { Console.WriteLine(item.Age+"="+item.GroupCounts); } Console.ReadKey(); } }
public class GroupCount { public int Age { get; set; } public int GroupCounts { get; set; } }
三、EF對象的狀態
EF中的對象有五個狀態: Derached(游離態,脫離態),Unchange(未改變),Added(新增),Deleted(刪除),Modified(被修改)