談EntityFramework數據更新之技巧

EntityFramework是一個很不錯的ORM框架,一直都在使用。今天想跟你們分享如下EntityFramework數據更新方面的幾個技巧:
 1:如何new一個新實體去更新記錄,而不是從數據庫中查詢一條記錄來更新。
 2:如何在更新實體的同時,對導航屬性的實體進行一系列的操做。
 3:如何用最簡單的代碼實現實體的部分更新。數據庫

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         }
View Code

若是註釋掉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

相關文章
相關標籤/搜索