談EntityFramework數據更新之技巧


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

new一個新實體去更新記錄

EntityFramework有一個特點,你無須查詢出一個記錄,而是new一個新實體,然后對其進行刪除或更新操作,只須提供實體的ID即可,如果ID不存在將會拋出異常。這樣有助於提高性能,畢竟減少了一次數據庫訪問。要實現用一個新實體去更新記錄,你得讓EF的Change Tracker跟蹤該實體,讓它認為該實體就是從數據庫中取出來的,只要讓改該實體處於修改狀態就行了,代碼如下:

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操作就行了,代碼如下:

 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)這行代碼,將會拋出異常,這個是值得注意的地方。

3 實現實體的部分更新
以前好像在園子里有朋友講過Entityframework實體部分更新的問題,就是用反射去遍歷實體的屬性,把需要修改的實體屬性狀態設置為Modified,這樣也可以達到目的,但是這樣寫的代碼有點多,而且對Entityframework的特性沒有充分的利用,其實很簡單兩行代碼就搞定:

 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即可,綜合兩種情況,合並的代碼如下:

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操作將修改該實體。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM