2011-06-13 110 views
1

我使用LinqToEntitiesDomainService類來更新Silverlight 4客戶端的數據庫。 還有的AttachAsModified爲實體框架ObjectContext的擴展方法,它允許您提供原始的實體屬性值:WCF RIA Services SP1,實體框架4,僅更新更改的列

Order original = this.ChangeSet.GetOriginal(currentOrder); 
this.ObjectContext.Orders.AttachAsModified(currentOrder, original); 

默認情況下,WCF RIA服務不發送原始值到服務器,所以人們需要 應用[RoundtripOriginal( )]屬性給他/她的實體。

但是,即使我提供原始值,由Entity框架生成的SQL更新所有列,不僅更改了所有列。由於AttachAsModified()方法不是本地ObjectContext類方法(它是在ObjectContextExtensions類中定義的擴展方法),因此我嘗試使用在ObjectSet類中定義的ApplyOriginalValues方法 。不用找了。 看來最近發佈的實體框架4.1可能有解決方案(不確定)。實體框架4如何? EF有可能生成sql來只更新更改的列嗎?

回答

1

我曾問在MSDN論壇類似的問題,並確認WCF RIA Services將更改所有列。替代方案是,

您可以從數據庫獲取副本,使用反射手動比較SetModifiedProperty並進行標記。

// change state of entity as Unmodified/Unchanged... 
original.EntityState = Unchanged; 

// this is copy form database... 
// Use different context 
MyOrderContext context = new MyOrderContext(); 
Order dbOriginal = context.Orders.First(x=>x.OrderID == original.OrderID); 

foreach(PropertyInfo p in copy.GetTypes().GetProperties()){ 
    Object originalValue = p.GetValue(dbOriginal); 
    Object newValue = p.GetValue(original); 
    if(originalValue!=null && newValue!=null 
     && originalValue.Equals(newValue)){ 
     continue; 
    } 
    // resetting this will 
    // make entity's only current 
    // property as changed 
    p.SetValue(original,originalValue); 
    p.SetValue(original,newValue); 
} 

您可能需要更改代碼,每情況,檢查是否屬性是隻讀與否,這只是一個樣本,但它會幫助你建立在其上。

3

AttachAsModified會將實體標記爲已修改。隨後(引自MSDN):

當更改 實體對象條目修改時,對象的屬性的所有 被 標記爲修改,無論 電流或原始值的EntityState。

警告;我沒有這樣做,但是,它應該工作。

不使用AttachAsModified,而是使用ChangeState方法將實體標記爲UnChanged。

然後在已更改的屬性上使用SetModifiedProperty方法使它們包含在更新中。

編輯:如果你想辦法找到其性質已經改變,有一對夫婦的文章在那裏解釋如何使用做ObjectStateManagerthis one

+0

謝謝,我想標記你的答案也是正確的; SO不允許2個答案是正確的。 – synergetic 2011-06-14 00:06:52

+0

大多數歡迎和沒有問題,@阿卡什的代碼示例確實比我的MSDN報價更容易。 =) – Smudge202 2011-06-14 08:10:10

1

我設法做到這一點,首先附加對象,然後在EntitySet上調用ApplyOriginalValues。你需要一個具有原始值的對象來做到這一點。該方法也可以用來防止列被更新,例如爲行級安全性。

注意:如果不先從數據庫中檢索原始實體,則不幸的是不起作用。否則,只有設置爲其默認值的屬性纔會從更新中排除...