天天看點

陷阱~EF中的Update與Insert共用一個資料上下文

事情是這樣的,有一個清單,裡面有很多使用者資訊,可能會有重複的使用者,将這個清單的使用者插入到資料表中,如果使用者已經存在,就更新這個使用者的FillTimes 字段,讓它加1,使用的底層ORM是entity frameworks4。

這是方法的大概内容

這個方法看似沒有任何問題,當一個使用者沒有在表中存在,就insert,如果存在了,就update,這是再簡單不過的邏輯了,然而,如果你的iRepository對象聲明

放錯了位置,可能問題就出來了,我們知道DbContext是有緩存的,當一個實體被送出後,它可能在緩存裡還會存在,直到DbContext被dispose之後,它才會

消失,這就是說,如果insert與update使用的是同一個DbContext,就會出現一個異常,“不能在相同的對象上建立新實體”,而一般地,insert與update不能不同存在,這是我們可以想像的,而我們可能往往忽略了DbContext是否為一個,如果insert或者update之後,DbContext對象沒有被銷毀,那異常就會出現了。

而在本例中,iRepository的聲明與執行個體化是在方法體外部完成的,而這個方法就是在被集合周遊時調用的,這時,你的iRepository裡的DbContext對象就成了一個,在這個方法的生命周期時,你的資料上下文是一個,你的update操作也就出現問題了,呵呵。

如果你的代碼是這樣寫的話,那在周遊調用 InsertOrUpdateUser方法時,就有可能出現上面的異常了,呵呵!

正确的作法是将var iRepository=new Repository<User>();這句話移到InsertOrUpdateUser方法體裡,問題就解決了。

繼續閱讀