EntityFramework是一個很不錯的ORM框架,一直都在使用。今天想跟你們分享如下EntityFramework數據更新方面的幾個技巧:
1:如何new一個新實體去更新記錄,而不是從數據庫中查詢一條記錄來更新。
2:如何在更新實體的同時,對導航屬性的實體進行一系列的操做。
3:如何用最簡單的代碼實現實體的部分更新。數據庫
1 new一個新實體去更新記錄框架
EntityFramework有一個特色,你無須查詢出一個記錄,而是new一個新實體,而後對其進行刪除或更新操做,只須提供實體的ID便可,若是ID不存在將會拋出異常。這樣有助於提升性能,畢竟減小了一次數據庫訪問。要實現用一個新實體去更新記錄,你得讓EF的Change Tracker跟蹤該實體,讓它認爲該實體就是從數據庫中取出來的,只要讓改該實體處於修改狀態就好了,代碼以下:ide
1 context.Entry<TEntity>(entity).State = EntityState.Modified; 2 context.SaveChanges();
2 更新實體時操做導航屬性
用一個例子來講明在更新實體同時如何對導航屬性進行操做吧。假設有兩個類型
public class Customer
{
public string ID { get; set; }
public string Name { get; set; }
public IList<CustomerAddress> CustomerAddresses { get; set; }
}性能
public class CustomerAddress
{
public string City { get; set; }
public string ZipCode { get; set; }
public string CustomerId { get; set; }
public Customer Customer { get; set; }
}
那如何在更新Customer的同時Add一個CustomerAddress而且Delete一個CustomerAddress呢?關鍵一點就是要讓EntityFramework的Change Tracker知道有CustomerAddress的存在,只需對Customer增長一個Add操做就好了,代碼以下:spa
1 public void Modify(Customer entity,CustomerAddress address) 2 { 3 context.Customer.Add(entity); 4 5 //修改Customer 6 context.Entry(entity).State = EntityState.Modified; 7 8 //新增CustomerAddress 9 if (......) 10 { 11 entity.CustomerAdresses.Add(address); 12 } 13 14 //刪除CustomerAddress 15 if (.......) 16 { 17 context.Entry(address).State = EntityState.Deleted; 18 } 19 context.SaveChanges(); 20 }
若是註釋掉context.Customer.Add(entity)這行代碼,將會拋出異常,這個是值得注意的地方。code
3 實現實體的部分更新
之前好像在園子裏有朋友講過Entityframework實體部分更新的問題,就是用反射去遍歷實體的屬性,把須要修改的實體屬性狀態設置爲Modified,這樣也能夠達到目的,可是這樣寫的代碼有點多,並且對Entityframework的特性沒有充分的利用,其實很簡單兩行代碼就搞定:blog
1 /// <summary> 2 /// 實體部分更新 3 /// </summary> 4 /// <param name="originalEmployee">需修改的實體</param> 5 /// <param name="newEmployee">新的實體</param> 6 public void Modify(Employee originalEmployee, Employee newEmployee) 7 { 8 context.Entry(originalEmployee).CurrentValues.SetValues(newEmployee); 9 context.SaveChanges(); 10 }
關鍵是第一行代碼,意思就是把原來實體的值設置爲新實體的值,你們能夠查看CurrentValues.SetValues()這個方法的源代碼,就能明白其中的道理。在執行查詢的時候你們 能夠打開SQLServer Profiler查看是否真的是部分更新了。若是該實體是一個新實體,該如何更新呢?仍是老辦法讓EntityFramework知道它的存在,把它的狀態設置爲UnChanged便可,綜合兩種狀況,合併的代碼以下:ip
public void Modify(Employee originalEmployee, Employee newEmployee) { if (context.Entry(originalEmployee).State != EntityState.Unchanged) context.Entry(originalEmployee).State = EntityState.Unchanged; context.Entry(originalEmployee).CurrentValues.SetValues(newEmployee); context.SaveChanges(); }
其實今天講的都是new一新實體去更新數據庫,關鍵是讓EF 的Change Tracker跟蹤新實體這樣才能達到修改的目的,而這一切都是設置EntityState才行。
順便提一下EntityState,它是一枚舉類型,有Detached,Unchanged,Added,Deleted,Modified五個值分別表明:實體沒被跟蹤,啥操做對它無效;實體存在於數據庫但還沒被修改;實體被跟蹤但不存在於數據庫,實體存在於數據庫而且標記爲刪除,SaveChanges操做將刪除該實體;實體存在於數據庫而且標記爲修改,SaveChanges操做將修改該實體。get