事情是這樣的,有一個列表,里面有很多用戶信息,可能會有重復的用戶,將這個列表的用戶插入到數據表中,如果用戶已經存在,就更新這個用戶的FillTimes 字段,讓它加1,使用的底層ORM是entity frameworks4。
這是方法的大概內容
var user_Account = iC_User_Account.Find(i => i.UserID == u.UserID); if (user_Account == null) { iRepository.Insert(new C_User_Account { AccountID = 1, AddTime = rechargeTime, BeginDate = rechargeTime, EndDate = rechargeTime.AddYears(100), FillTimes = 1, Income = 0, Incoming = 0, LockMoney = 0, Outgoings = card.CardValue, Status = 1, UserID = u.UserID, UserType = 1, }); } else { user_Account.FillTimes = user_Account.FillTimes ?? 0 + 1; iRepository.Update(user_Account); }
這個方法看似沒有任何問題,當一個用戶沒有在表中存在,就insert,如果存在了,就update,這是再簡單不過的邏輯了,然而,如果你的iRepository對象聲明
放錯了位置,可能問題就出來了,我們知道DbContext是有緩存的,當一個實體被提交后,它可能在緩存里還會存在,直到DbContext被dispose之后,它才會
消失,這就是說,如果insert與update使用的是同一個DbContext,就會出現一個異常,“不能在相同的對象上建立新實體”,而一般地,insert與update不能不同存在,這是我們可以想像的,而我們可能往往忽略了DbContext是否為一個,如果insert或者update之后,DbContext對象沒有被銷毀,那異常就會出現了。
而在本例中,iRepository的聲明與實例化是在方法體外部完成的,而這個方法就是在被集合遍歷時調用的,這時,你的iRepository里的DbContext對象就成了一個,在這個方法的生命周期時,你的數據上下文是一個,你的update操作也就出現問題了,呵呵。
//定義一個數據操作對象 var iRepository=new Repository<User>(); //供外部調用的更新用戶列表的方法 public void UpdateUser(List<User> list) { userList.ForEach(i=>{ InsertOrUpdateUser(i); }); }
如果你的代碼是這樣寫的話,那在遍歷調用 InsertOrUpdateUser方法時,就有可能出現上面的異常了,呵呵!
正確的作法是將var iRepository=new Repository<User>();這句話移到InsertOrUpdateUser方法體里,問題就解決了。
文章列表