正常狀況下的增刪改查代碼:sql
#region 1.0 新增 -void Add() /// <summary> /// 1.0 新增 /// </summary> static void Add() { //1.1建立實體對象 User uObj = new User() { uName = "劉德華", uLoginName = "aaa", uPwd = "asdfasdfasdfsadf", uIsDel = false, uAddtime = DateTime.Now }; //1.2經過EF新增到數據庫 //1.2.1將對象 加入到 數據上下文 的 User集合中 //db.Users.Add(uObj); DbEntityEntry<User> entry = db.Entry<User>(uObj); entry.State = System.Data.EntityState.Added; //1.2.2調用數據上下文 的 保存方法,將 對象 存數數據庫 db.SaveChanges(); Console.WriteLine("保存成功~~!"); } #endregion #region 2.0 簡單查詢 -void Query() /// <summary> /// 2.0 簡單查詢 /// </summary> static void Query() { //2.0 IEnumerable(集合) 和 IQueryable(EF裏的DbSet<T>) 裏的 SQO 本質不同!: //2.1 集合 的 標準查詢運算符 方法 ,是來自於 System.Linq.Enumerable 裏 給 IEnumerable 接口添加的擴展方法 //List<string> listStr = new List<string>(); //listStr.Where //EF上下文裏的 DBSet<T> 裏的 標準查詢運算符 方法,來自於 System.Linq.Queryable 裏給 IQueryable接口 添加的擴展方法 //2.2 變相的 即時查詢 List<User> list = db.Users.Where(u => u.uName == "劉德華").ToList(); list.ForEach(u => Console.WriteLine(u.ToString())); } #endregion #region 2.1 簡單查詢 延遲加載 -void QueryDelay_01() //【延時加載】 當作兩種: //2.1 EF自己查詢方法 返回的都是 IQueryable接口,此時並未查詢數據庫;只有當調用接口方法 獲取 數據時,纔會查詢數據庫 //2.1.1 【延時加載】,本質緣由之一:當前可能經過多個SQO方法 來組合 查詢條件,那麼每一個方法 都只是添加一個查詢條件而已,沒法肯定本次查詢條件 是否 已經添加結束 // 因此,沒有辦法在每一個SQO方法的時候肯定SQL語句是什麼,只能返回一個 包含了全部添加的條件的 DBQuery 對象, // 當使用這個 DBQuery對象 的時候,才根據全部條件 生成 sql語句,查詢數據庫 static void QueryDelay_01() { DbQuery<User> dbQuery = db.Users.Where(u => u.uLoginName == "劉德華").OrderBy(u => u.uName).Take(2) as System.Data.Entity.Infrastructure.DbQuery<User>; //得到 延遲查詢對象後,調用對象的 獲取第一個數據方法,此時,【就會根據以前的條件】,生成sql語句,查詢數據庫了~~! User usr01 = dbQuery.FirstOrDefault();// ToList()...... Console.WriteLine(usr01.uLoginName); } //2.1.2【延遲加載】- 針對於 外鍵實體 的延遲(按需加載)! // 本質緣由之二:對於外鍵屬性而言,EF會在用到這個外鍵屬性的時候纔去查詢 對應的 表。 static void QueryDelay_02() { IQueryable<UsersAddress> addrs = db.UsersAddresses.Where(a => a.udUId == 1);//真實返回的 DbQuery 對象,以接口方式返回 //a.此時只查詢了 地址表 UsersAddress addr01 = addrs.FirstOrDefault(); //b.當訪問 地址對象 裏的 外鍵實體時,EF會查詢 地址對應 的用戶表;查詢到以後,將數據 裝入 這個外鍵實體 Console.WriteLine(addr01.User.uName); //c.【延遲加載】按需加載 的缺點:每次調用外鍵實體時,都會去查詢數據庫(EF有小優化:相同的外鍵實體只查一次) IQueryable<UsersAddress> addrs2 = db.UsersAddresses; foreach (UsersAddress add in addrs2) { Console.WriteLine(add.udAddress + ":userName=" + add.User.uName); } } #endregion #region 2.2 鏈接查詢(生成 inner join) -void QueryInnerJoin() /// <summary> /// 2.2 鏈接查詢(生成 inner join) /// </summary> static void QueryInnerJoin() { //經過Include方法,設置 EF 生成 sql 語句時,使用 inner join 把 地址表對應的 User屬性 也查出來 // select * from UsersAddresses a inner join Users u on a.udId =u.id IQueryable<UsersAddress> addrs = db.UsersAddresses.Include("User").Where(a => a.udId == 1); foreach (UsersAddress add in addrs) { Console.WriteLine(add.udAddress + ":userName=" + add.User.uName); } //練習:查詢消息表的同時,顯示 消息發送人 和 接收名字 IQueryable<Msg> msgs = db.Msgs.Include("User").Include("User1"); foreach (Msg m in msgs) { Console.WriteLine(m.mId + ",發送人:" + m.User.uName + ",接收人:" + m.User1.uName + ",消息內容:" + m.mMsg); } } #endregion #region 3.0 官方推薦的 修改方式(先查詢,再修改) /// <summary> /// 3.0 官方推薦的 修改方式(先查詢,再修改) /// </summary> static void Edit() { //1.查詢出一個 要修改的對象 -- 注意:此時返回的 是 一個 User類的 代理類對象(包裝類對象) User usr = db.Users.Where(u => u.uId == 1).FirstOrDefault(); Console.WriteLine("修改前:" + usr.ToString()); //2.修改內容 -- 注意:此時其實操做的 是 代理類對象 的屬性,這些屬性,會將 值 設置給 內部的 User對象對應的屬性,同時 標記此屬性爲已修改狀態 usr.uName = "劉德華"; usr.uLoginName = "liudehua"; //3.從新保存到數據庫 -- 注意:此時 ef上下文,會檢查容器內部 全部的對象,找到 標記爲修改的 對象,而後 找到 標記爲修改的 對象屬性,生成對應的 update語句 執行! db.SaveChanges(); Console.WriteLine("修改爲功:"); Console.WriteLine(usr.ToString()); } #endregion #region 3.1 本身優化的 修改方式(建立對象,直接修改) /// <summary> /// 3.1 本身優化的 修改方式(建立對象,直接修改) /// </summary> static void Edit2() { //1.查詢出一個 要修改的對象 User usr = new User() { uId = 8,uName="小白~~~"}; //2.將 對象 加入 EF容器,並獲取 當前實體對象 的 狀態管理對象 DbEntityEntry<User> entry = db.Entry<User>(usr); //3.設置 該對象 爲被修改過 entry.State = System.Data.EntityState.Unchanged; //4.設置 該對象 的 uName屬性 爲 修改狀態,同時 entry.State 被修改成 Modified 狀態 entry.Property("uName").IsModified = true; //var u = db.Users.Attach(usr); //u.uName = "小白~~"; //3.從新保存到數據庫 -- ef 上下文 會 根據 實體對象的 狀態 ,根據 entry.State =Modified 的值 生成 對應的 update sql 語句 db.SaveChanges(); Console.WriteLine("修改爲功:"); Console.WriteLine(usr.ToString()); } #endregion #region 4.0 刪除 -void Delete() /// <summary> /// 4.0 刪除 /// </summary> static void Delete() { //4.1建立要刪除的 對象 User u = new User() { uId = 10 }; //4.2附加到 EF中 db.Users.Attach(u); //4.3標記爲刪除 注意:此方法 就是 起到了 標記 當前對象 爲 刪除狀態 ! db.Users.Remove(u); /* 也可使用 Entry 來附加和 修改 DbEntityEntry<User> entry = db.Entry<User>(u); entry.State = System.Data.EntityState.Deleted; */ //4.4執行刪除sql db.SaveChanges(); Console.WriteLine("刪除成功~~~"); } #endregion #region 5.0 批處理 -- 上下文 SaveChanges 方法 的 好處!!!! /// <summary> /// 批處理 -- 上下文 SaveChanges 方法 的 好處!!!! /// </summary> static void SaveBatched() { //5.1新增數據 User uObj = new User() { uName = "劉德華", uLoginName = "aaa", uPwd = "asdfasdfasdfsadf", uIsDel = false, uAddtime = DateTime.Now }; db.Users.Add(uObj); //5.2新增第二個數據 User uObj2 = new User() { uName = "劉德華2", uLoginName = "aaa2", uPwd = "asdfasdfasdfsadf2", uIsDel = false, uAddtime = DateTime.Now }; db.Users.Add(uObj2); //5.3修改數據 User usr = new User() { uId = 8, uName = "又黑了~~~" }; DbEntityEntry<User> entry = db.Entry<User>(usr); entry.State = System.Data.EntityState.Unchanged; entry.Property("uName").IsModified = true; //5.4刪除數據 User u = new User() { uId = 11 }; //4.2附加到 EF中 db.Users.Attach(u); //4.3標記爲刪除 注意:此方法 就是 起到了 標記 當前對象 爲 刪除狀態 ! db.Users.Remove(u); db.SaveChanges(); Console.WriteLine("批處理 完成~~~~~~~~~~~~!"); } #endregion #region 5.1 批處理 -- 一次新增 50條數據 -void BatcheAdd() /// <summary> /// 5.1 批處理 -- 一次新增 50條數據 /// </summary> static void BatcheAdd() { for (int i = 0; i < 50; i++) { User uObj = new User() { uName = "劉德華" + i, uLoginName = "aaa" + i, uPwd = "asdfasdfasdfsadf" + i, uIsDel = false, uAddtime = DateTime.Now }; db.Users.Add(uObj); } db.SaveChanges(); } #endregion
直接調用sql語句的方法數據庫
db.Database.ExecuteSqlCommand(""); //db.Database.SqlQuery //db.Database.SqlQuery<T>