2013-05-04 45 views
0

我正在使用EF 4.4,我想更新許多實體,但其他一些用戶可以修改許多第一個用戶修改的實體。所以我得到了一個併發異常。其他情況是,第一個用戶嘗試添加許多新的寄存器,而其他用戶同時添加了一些新的寄存器。所以我有一個存在一些寄存器的異常(唯一約束)。這是刷新dbContext這兩種方式的區別嗎?

我想確保第一個用戶完成他的操作,只添加不存在的寄存器(添加除第二個用戶添加的實體外的所有實體)。

爲此,我需要更新我的dbContext中的實體,以便我看到至少有兩個選項。

首先,當我捕捉更新異常捕獲,我可以這樣做:

ex.Entries.Single().Reload(); 

第二個選項是:

myContext.Entry<MyTable>(instance).Reload(); 

我想,第二個選項只刷新我用作參數的實體,但如果問題是我需要刷新許多實體,那我該怎麼做?

第一個選項Single().Reload是什麼?

回答

1

當你

ex.Entries.Single().Reload(); 

您確信違規實體將被刷新。現在做的是將DbUpdateConcurrencyException.Entries中唯一的(Single)實體無法保存到數據庫(在發生併發異常的情況下,它總是隻有一個)。

當你

myContext.Entry(instance).Reload(); 

您是確保您刷新右實體,除非你知道,只有一個實體有變化SaveChanges被稱爲前。如果使用子實體保存實體,則其中任何一個都會導致併發問題。

+0

如果有很多違規實體,它們全部被刷新或者只能一個一個地刷新? – 2013-05-05 06:53:03

+0

總是有一個。 EF分別保存每個對象,導致衝突的第一個引發異常。當然,可能會有更多的事情會導致碰撞,但是他們還沒有得到保存,所以EF不知道他們應該被刷新。他們會在下次嘗試保存時發現。 – 2013-05-05 08:20:37

0

在EF 6.x(6.1.3)中,下面的代碼可以讓你找到所有的變化;你在問題中問的方式!

try 
{ 
    var listOfRefreshedObj = db.ChangeTracker.Entries().Select(x => x.Entity).ToList(); 
    var objContext = ((IObjectContextAdapter)your_db_context).ObjectContext; 
    objContext.Refresh(System.Data.Entity.Core.Objects.RefreshMode.ClientWins, listOfRefreshedObj); 

    await db.Entry(<yourentity>).ReloadAsync(); 
    return Content(HttpStatusCode.<code>, "<outputmessage>"); ; 
} 
catch (Exception e) 
{ 
    return Content(HttpStatusCode.<code>, "<exception>"); 
} 

釋: 查詢EntriesChangeTracker並將其存儲在一個列表

var listOfRefreshedObj = db.ChangeTracker.Entries().Select(x => x.Entity).ToList(); 

接下來是刷新背景。在某些情況下(行被刪除等),這將拋出一個異常,你可以捕捉。 RefreshMode.ClientWins通知EF在下次更新時接受所有修改的客戶端單元。在某些情況下,您可能想要提示用戶進行更改並讓他們決定。 RefreshMode Enumeration。一個例子是在這裏ObjectContext.Refresh Method Example

objContext.Refresh(System.Data.Entity.Core.Objects.RefreshMode.ClientWins, listOfRefreshedObj); 

收到DbUpdateConcurrencyException後反正你可能會做這件事!

相關問題