我使用EF 6.1處理併發和我的服務更新方法看起來像這樣設定值和EF 6
public async override Task<int> UpdateAsync(Module updated)
{
var entity = await _context.Modules
.Where(e => e.Id == updated.Id)
.FirstOrDefaultAsync();
// update existing values
_context.Entry(entity).CurrentValues.SetValues(updated);
// do not update
_context.SetModified(entity, "AddOnlyProperty", false);
return await base.UpdateAsync(entity);
}
我的基本UpdateAsync看起來像這樣
public async virtual Task<int> UpdateAsync(T updated)
{
var results = await ValidateAsync(updated);
if (!results.IsValid)
{
throw new ValidationException(results.Errors);
}
if (_context.GetState(updated) == EntityState.Detached)
{
_context.Set<T>().Attach(updated);
_context.SetState(updated, EntityState.Modified);
}
// we do not want the createdDate to change when an update is being done
_context.SetModified(updated, "CreatedDate", false);
_context.SetModified(updated, "CreatedByUserId", false);
return await _context.SaveChangesAsync();
}
這個方法很簡單,它會將更新後的更改複製到實體中,這樣EF只會在創建SQL時應用所需的更改。
我的問題是併發不似乎工作,我會期待一個DbConcurrencyException被拋出?
這裏是我的基本模塊對象
public class Module : EntityBase, IEntityVersion, IEntityDelete
{
public long Id { get; set; }
public string Name { get; set; }
public byte[] RowVersion { get; set; }
}
當我和一個老執行更新我已經配置RowVersion在我Module.config文件rowVersion場,像這樣
this.Property(e => e.RowVersion)
.IsRowVersion();
現在rowVersion值,更新似乎仍然發生?我錯過了一個配置設置還是我做錯了?
應該拋出一個異常,或者我應該檢查rowVersion值是否與我自己匹配?
但如果我檢索實體,並覆蓋它的值行版本肯定會被覆蓋,因此它應該使用這個值來檢查它是否是最新版本?或者是你說,因爲我從數據庫檢索它,實體框架認爲它應該是最新版本無論如何,並忽略它? – Gillardo
你能告訴我一個如何跟蹤變化的例子嗎?只有這樣做才能修改已更改的屬性 – Gillardo
@ user2736022實體框架使用更改跟蹤,併爲所有屬性保留舊值和新值(如果實體未更改,則舊值和新值相同)。它使用行版本的舊值進行併發檢查,並忽略您嘗試給出的任何新值。在你的情況下,EF看作舊值的值實際上並不是你希望用於併發檢查的舊值。 – hvd