我正在使用RIA服務,其中ObjectContext具有RejectChanges()方法。但是,我現在正在使用EF 4.4在桌面應用程序中,並且找不到該方法。所以,我的問題是:在允許用戶對collection進行批量CrUD操作的場景中,我將如何恢復所有更改?我可以重新創建上下文並再次獲取數據,但如果我需要將更改還原回1-2個實體,則這聽起來非常不必要。DbContext和RejectChanges
那麼,拒絕更改的最佳方法是什麼?而且,我們如何知道上下文是否正在做某件事(IsBusy)?
我正在使用RIA服務,其中ObjectContext具有RejectChanges()方法。但是,我現在正在使用EF 4.4在桌面應用程序中,並且找不到該方法。所以,我的問題是:在允許用戶對collection進行批量CrUD操作的場景中,我將如何恢復所有更改?我可以重新創建上下文並再次獲取數據,但如果我需要將更改還原回1-2個實體,則這聽起來非常不必要。DbContext和RejectChanges
那麼,拒絕更改的最佳方法是什麼?而且,我們如何知道上下文是否正在做某件事(IsBusy)?
EF沒有任何直接「拒絕變更」操作。您可以通過ChangeTracker
/ObjectStateManager
中的實體條目並覆蓋修改實體原始值的當前值。您也可以分離添加的實體並將已刪除的實體更改回原來的狀態,但只有當您(或EF內部)未更改任何獨立關聯(關係)的狀態時,所有這些功能纔會工作。如果你和關係一起工作,整個事情會變得更加複雜,因爲你必須恢復關係 - 在這種情況下,重新加載數據更簡單。
對於的DbContext API還原更改你可以試試這個:
foreach (var entry in context.ChangeTracker
.Entries<YourEntityType>()
.Where(e => e.State == EntityState.Modified))
{
entry.CurrentValues.SetValues(entry.OriginalValues);
}
在這種情況下,我認爲主要的問題是你有實體如何工作的方式 - 你允許對實時數據的變化和EF做它的邏輯在執行更改時保持數據一致,但稍後您決定不保存這些更改。在這種情況下,你應該做下列之一:
上下文正在做某件事情,如果你說它做某事。它永遠不會變得繁忙。
這個工作對我來說:
public void RejectChanges() {
var context = ((IObjectContextAdapter)this).ObjectContext;
foreach (var change in this.ChangeTracker.Entries()) {
if (change.State == EntityState.Modified) {
context.Refresh(RefreshMode.StoreWins, change.Entity);
}
if (change.State == EntityState.Added) {
context.Detach(change.Entity);
}
}
}
這個=的DbContext在這種情況下
刪除的實體呢?另外,如何爲其他用戶更改的實體獲取新數據,而不是您? – Goran
我知道這是一個老問題。但是,沒有一個答案符合我的情況。我需要拒絕集合中只有一個實體的更改。這是對我工作:
var objectContext = (myDbContext as IObjectContextAdapter).ObjectContext;
objectContext.Refresh(RefreshMode.StoreWins, partMaster);
public void RejectChanges()
{
foreach (var entry in ChangeTracker.Entries())
{
switch (entry.State)
{
case EntityState.Modified:
{
entry.CurrentValues.SetValues(entry.OriginalValues);
entry.State = EntityState.Unchanged;
break;
}
case EntityState.Deleted:
{
entry.State = EntityState.Unchanged;
break;
}
case EntityState.Added:
{
entry.State = EntityState.Detached;
break;
}
}
}
}
這可能是一個古老的答案,但有用的任何新的訪問者.... 的刷新功能將重新載入數據源對象並覆蓋現有的變化新加載的實體的狀態將保持不變。
public static void UndoEntityChanges(object Entity)
{
<EFModelContainer>.Entry(Entity).Reload();
}
重新創建上下文將是一個很好的解決方案。但是,我在同步相關數據時遇到了問題。一個例子是,我在ViewA上的CollectionA上有CRUD,在ViewB上有在COllectionB上的CRUD。 CollectionB還擁有對CollectionA的引用。因此,如果我有2個Context對象(既適用於CollectionA也適用於CollectionB),如果我更改ViewA的CollectionA,如何同步ViewB?當有一個上下文時,所有內容都是同步的,因爲我們實際上只處理一個實例collectionA,而不是兩個。重新創建「全局」上下文會造成混亂。 :)我使用「全局」上下文犯了錯誤嗎? – Goran
至於「忙」,我擔心如果我發出一個異步加載負載會發生什麼,然後我嘗試發出另一個負載,而以前沒有完成?這樣我可以檢查它是否「忙碌」,這樣我可以排隊一個新的Load。 – Goran
+1注意到大多數人似乎錯過了什麼。關係:可以通過查看State!= Unchanged的Entries集合來追蹤那些不會被拾取的變化。 (EF v6。) – mwardm