EF(EntityFrameWork) ORM(對象關系映射框架/數據持久化框架),根據實體對象操作數據表中數據的一種面向對象的操作框架,底層也是調用ADO.NET
ASP.NET MVC 項目會自動導入MVC程序集,因為默認.NET環境(GAC)中沒有這個程序集
1: EF數據上下文 繼承於 DbContext ; DBQuery<T> ,支持延遲加載:只有當使用到數據的時候,才去查詢數據庫; 主要成員:表映射的實體集合 Set<T>,Entry<T>()
context.Model -->Dbset<Model>
context.set<Model>() -->Dbset<Model>
//使用狀態版的時候,執行修改/刪除的時候必須指定主鍵。
2: EF中會為每個 管理的 實體對象 創建一個代理包裝類對象,其中會跟蹤 實體對象 的狀態和每個屬性的狀態;
3: [EF對象管理容器]: 每個通過EF數據上下文操作的實體對象,都需要存在上下文的容器中,一旦通過上下文的某個方法操作了實體對象后,那么上下文就會給它加一個狀態標識。
但調用上下文的SaveChanges方法的時候,上下文就會遍歷容器中的所有對象,並檢查他們的狀態標識,並依照標識的值進行相應的增刪改查sql操作
一、通常使用EF更新的方式,先查詢出要修改的數據,然后再修改新的值;實體對象被修改的屬性 在 代理包裝類對象里 的對應屬性狀態會被修改記錄下修改狀態,
等到調用SaveChanges時,EF會遍歷其管理的每個實體對象,並根據其 包裝類對象 的狀態,生成增刪改查sql語句並執行;
此例中修改操作,會生成 修改的sql語句(注意:此處只為修改過的屬性生成sql語句),最后執行。

1 create database MyFirstEF 2 on primary 3 ( 4 name='MyFirstEF.mdf', 5 --修改為自己電腦上SQL DB路徑 6 filename='E:\ProgramMSSQLServerDB\MyFirstEF.mdf', 7 size=5mb, 8 maxsize=100mb, 9 filegrowth=10% 10 ) 11 log on 12 ( 13 name='MyFirstEF_log.ldf', 14 --修改為自己電腦上SQL DB路徑 15 filename='E:\ProgramMSSQLServerDB\MyFirstEF_log.ldf', 16 size=2mb, 17 maxsize=100mb, 18 filegrowth=5mb 19 ) 20 go 21 22 use MyFirstEF 23 go 24 25 create table CustomerInfo 26 ( 27 id int identity(1,1) primary key, 28 customerName nvarchar(100) not null, 29 customerDate datetime 30 ) 31 go 32 33 insert into CustomerInfo values('aaaaa',getdate()) 34 go 35 36 select * from CustomerInfo 37 go 38 39 create table OrderInfo 40 ( 41 id int identity(1,1) primary key, 42 orderName nvarchar(100), 43 customerId int 44 ) 45 go 46 47 48 alter table OrderInfo 49 add constraint FK_OrderInfo_CustomerInfo 50 foreign key(customerId) references CustomerInfo(id) 51 on delete cascade 52 on update cascade 53 54 go 55 56 57 select * from CustomerInfo 58 select * from OrderInfo
//EF context 對象 MyFirstEFEntities context = new MyFirstEFEntities(); //update //1:先查詢要修改的原數據 CustomerInfo customer = context.CustomerInfoes.Find(1); //2:設置修改后的值 customer.customerDate = DateTime.Now; //3:更新到數據庫 context.SaveChanges();
二、為避免先查詢數據庫,可以直接將 被修改的實體對象 添加到 EF中管理(此時為附加狀態Attached),並手動設置其為未修改狀態(Unchanged),
同時設置被修改的實體對象的包裝類對象 對應屬性為修改狀態。
//EF context 對象 DbContext contextState = new MyFirstEFEntities(); //update CustomerInfo customerState = new CustomerInfo(); customerState.id = 1; customerState.customerDate = DateTime.Now; customerState.customerName = "bbb"; //1: 標記當前對象,必須把必填字段都填寫,否則會報錯:System.Data.Entity.Validation.DbEntityValidationException //1: 若此時未更新 非必填字段,則數據庫會把非必填字段更新為null contextState.Entry<CustomerInfo>(customerState).State = System.Data.EntityState.Modified; contextState.SaveChanges();
//EF context 對象 DbContext contextState = new MyFirstEFEntities(); //update 2 CustomerInfo customerState = new CustomerInfo(); customerState.id = 1; customerState.customerName = "dfdfdfdf"; //2: 針對某個屬性,進行狀態跟蹤設置 //** 2.1: 如果使用 Entry 附加 實體對象到數據容器中,則需要手動 設置 實體包裝類的對象 的 狀態為 Unchanged** //** 2.1: entry.State = System.Data.EntityState.Unchanged; DbEntityEntry<CustomerInfo> entry = contextState.Entry<CustomerInfo>(customerState); entry.State = System.Data.EntityState.Unchanged; entry.Property("customerName").IsModified = true; contextState.SaveChanges();
//EF context 對象 DbContext contextState = new MyFirstEFEntities(); //update 3 CustomerInfo customerState = new CustomerInfo(); customerState.id = 1; customerState.customerName = "aaaaa"; //** 2.2: 如果使用 Attach 就不需要這句 //** 2.2: entry.State = System.Data.EntityState.Unchanged; contextState.Set<CustomerInfo>().Attach(customerState);///直接針對屬性進行狀態設置,但是當前對象並沒有被上下文跟蹤 contextState.Entry<CustomerInfo>(customerState).Property("customerName").IsModified = true; contextState.SaveChanges();
#region 多表增加操作 DbContext dbContext = new MyFirstEFEntities(); CustomerInfo customerInfo = new CustomerInfo() { customerName = "duobiaocaozuo", customerDate = DateTime.Now }; dbContext.Set<CustomerInfo>().Add(customerInfo); OrderInfo orderInfo1 = new OrderInfo() { orderName = "bike1", customerId = customerInfo.id }; dbContext.Set<OrderInfo>().Add(orderInfo1); OrderInfo orderInfo2 = new OrderInfo() { orderName = "bike2", customerId = customerInfo.id }; dbContext.Set<OrderInfo>().Add(orderInfo2); dbContext.SaveChanges(); #endregion
#region 導航屬性 DbContext dbContext = new MyFirstEFEntities(); CustomerInfo customerInfo = new CustomerInfo() { customerName = "daohangshuxing", customerDate = DateTime.Now }; customerInfo.OrderInfoes.Add(new OrderInfo() { orderName = "car1", }); customerInfo.OrderInfoes.Add(new OrderInfo() { orderName = "car2" }); dbContext.Set<CustomerInfo>().Add(customerInfo); dbContext.SaveChanges(); #endregion

1 using System; 2 using System.Collections.Generic; 3 using System.Data.Entity; 4 using System.Data.Entity.Infrastructure; 5 using System.Linq; 6 using System.Text; 7 using System.Threading.Tasks; 8 9 namespace _20160403_MyFirstEFDemo 10 { 11 class Program 12 { 13 static void Main(string[] args) 14 { 15 16 #region 方法 17 ////EF context 對象 18 //MyFirstEFEntities context = new MyFirstEFEntities(); 19 ////add 20 //CustomerInfo customer = new CustomerInfo(); 21 //customer.customerName = "Test1"; 22 //customer.customerDate = DateTime.Now; 23 //context.CustomerInfoes.Add(customer); 24 //context.SaveChanges(); 25 26 ////update 27 ////1:先查詢要修改的原數據 28 //CustomerInfo customer = context.CustomerInfoes.Find(1); 29 ////2:設置修改后的值 30 //customer.customerDate = DateTime.Now; 31 ////3:更新到數據庫 32 //context.SaveChanges(); 33 34 ////Read 35 //CustomerInfo customer = context.CustomerInfoes.Find(1); 36 //if (customer != null) 37 //{ 38 // string strCustomerInfo = string.Format("name:{0},date:{1}", customer.customerName, customer.customerDate); 39 // Console.WriteLine(strCustomerInfo); 40 //} 41 42 ////delete 43 //CustomerInfo customer = new CustomerInfo(); 44 //customer.id = 1; 45 //context.CustomerInfoes.Attach(customer); 46 //context.CustomerInfoes.Remove(customer); 47 //context.SaveChanges(); 48 #endregion 49 50 #region 狀態 51 //EF context 對象 52 //DbContext contextState = new MyFirstEFEntities(); 53 54 ////add 1 55 //CustomerInfo customerState = new CustomerInfo(); 56 //customerState.customerName = "testState1"; 57 //customerState.customerDate = DateTime.Now; 58 //contextState.Set<CustomerInfo>().Add(customerState); 59 //contextState.SaveChanges(); 60 61 ////add 2 62 //CustomerInfo customerState = new CustomerInfo() { 63 // customerName="stateTest111", 64 // customerDate=DateTime.Now 65 //}; 66 //contextState.Entry<CustomerInfo>(customerState).State = System.Data.EntityState.Added; 67 //contextState.SaveChanges(); 68 69 ////update 1 70 //CustomerInfo customerState = new CustomerInfo(); 71 //customerState.id = 1; 72 //customerState.customerDate = DateTime.Now; 73 //customerState.customerName = "bbb"; 74 75 ////1: 標記當前對象,必須把必填字段都填寫,否則會報錯:System.Data.Entity.Validation.DbEntityValidationException 76 ////1: 若此時未更新 非必填字段,則數據庫會把非必填字段更新為null 77 //contextState.Entry<CustomerInfo>(customerState).State = System.Data.EntityState.Modified; 78 //contextState.SaveChanges(); 79 80 ////update 2 81 //CustomerInfo customerState = new CustomerInfo(); 82 //customerState.id = 1; 83 //customerState.customerName = "dfdfdfdf"; 84 85 ////2: 針對某個屬性,進行狀態跟蹤設置 86 ////** 2.1: 如果使用 Entry 附加 實體對象到數據容器中,則需要手動 設置 實體包裝類的對象 的 狀態為 Unchanged** 87 ////** 2.1: entry.State = System.Data.EntityState.Unchanged; 88 //DbEntityEntry<CustomerInfo> entry = contextState.Entry<CustomerInfo>(customerState); 89 //entry.State = System.Data.EntityState.Unchanged; 90 //entry.Property("customerName").IsModified = true; 91 //contextState.SaveChanges(); 92 93 ////update 3 94 //CustomerInfo customerState = new CustomerInfo(); 95 //customerState.id = 1; 96 //customerState.customerName = "aaaaa"; 97 98 ////** 2.2: 如果使用 Attach 就不需要這句 99 ////** 2.2: entry.State = System.Data.EntityState.Unchanged; 100 //contextState.Set<CustomerInfo>().Attach(customerState);///直接針對屬性進行狀態設置,但是當前對象並沒有被上下文跟蹤 101 //contextState.Entry<CustomerInfo>(customerState).Property("customerName").IsModified = true; 102 //contextState.SaveChanges(); 103 104 ////delete 105 //CustomerInfo customerState = new CustomerInfo() 106 //{ 107 // id = 2 108 //}; 109 //contextState.Entry<CustomerInfo>(customerState).State = System.Data.EntityState.Deleted; 110 //contextState.SaveChanges(); 111 112 #endregion 113 114 #region 多表增加操作 115 //DbContext dbContext = new MyFirstEFEntities(); 116 117 //CustomerInfo customerInfo = new CustomerInfo() 118 //{ 119 // customerName = "duobiaocaozuo", 120 // customerDate = DateTime.Now 121 //}; 122 //dbContext.Set<CustomerInfo>().Add(customerInfo); 123 124 //OrderInfo orderInfo1 = new OrderInfo() 125 //{ 126 // orderName = "bike1", 127 // customerId = customerInfo.id 128 //}; 129 //dbContext.Set<OrderInfo>().Add(orderInfo1); 130 131 //OrderInfo orderInfo2 = new OrderInfo() 132 //{ 133 // orderName = "bike2", 134 // customerId = customerInfo.id 135 //}; 136 //dbContext.Set<OrderInfo>().Add(orderInfo2); 137 138 //dbContext.SaveChanges(); 139 #endregion 140 141 #region 導航屬性 142 //DbContext dbContext = new MyFirstEFEntities(); 143 144 //CustomerInfo customerInfo = new CustomerInfo() 145 //{ 146 // customerName = "daohangshuxing", 147 // customerDate = DateTime.Now 148 //}; 149 150 //customerInfo.OrderInfoes.Add(new OrderInfo() 151 //{ 152 // orderName = "car1", 153 //}); 154 155 //customerInfo.OrderInfoes.Add(new OrderInfo() 156 //{ 157 // orderName = "car2" 158 //}); 159 160 //dbContext.Set<CustomerInfo>().Add(customerInfo); 161 162 //dbContext.SaveChanges(); 163 164 #endregion 165 166 Console.WriteLine("OK"); 167 Console.ReadKey(); 168 } 169 } 170 }
參考文章:
ASP.NET EF(LINQ/Lambda查詢):http://www.cnblogs.com/Dr-Hao/p/5356928.html
ASP.NET EF 使用LinqPad 快速學習Linq:http://www.cnblogs.com/Dr-Hao/p/5357112.html
Ps:ViewBag,ViewData,TempData區別?
ViewBag 和 ViewData 數據"共享",作用域為 當前 Action。
TempData 作用域跨 Action。