場景:前幾天在項目開發時,有個bug經常出現,今天花了一整天,終於把它解決了。記錄一下解決流程。
解決方法:
主要報錯的地方在添加的部分:
1 foreach (var requestProperty in request.Properties) 2 { 3 UnitWork.Add(new Relevance 4 { 5 Key = Define.ROLEDATAPROPERTY, 6 FirstId = request.RoleId, 7 SecondId = request.ModuleCode, 8 ThirdId = requestProperty, 9 OperateTime = DateTime.Now 10 });UnitWork.save(); 11 }
這里的UnitWork(事務類)的Add()方法主要實現“上下文”的以下代碼:
1 _context.Set<T>().Add(entity);
而Save()實現以下代碼:
1 _context.SaveChanges();
我查了半天的問題,發現報錯都是:An error occurred while updating the entries. See the inner exception for detail。同時我打印了是哪個實體類的問題,發現每次實體類都不一樣。由於在這之前做了刪除的操作,一開始我以為是刪除的操作,可能是數據庫中數據沒刪干凈就開始添加,或者還沒刪完就開始添加,導致上下文對同一數據操作。后來跟蹤了一下斷點,查看一下數據庫,發現刪除的數據和添加的數據沒有關系。然后我猜會不會是UnitWork的問題,於是我用了Repository的Add(),其代碼如下;
1 public void Add(T entity) 2 { 3 _context.Set<T>().Add(entity); 4 _context.SaveChanges(); 5 _context.Entry(entity).State = EntityState.Detached; 6 }
和unitWork不同的是,這里的Add()方法中多加了一句:對上下文實體類狀態的操作。運行,發現成功了,沒有報錯。原來是Entry.State的關系。
原理:
先介紹一下實體的State:
Unchanged | 未修改。在加載到上下文后未修改 |
Modified | 已修改。已經修改,但是沒有使用savechange() |
Deleted | 已刪除。從上下文中刪除了對象,但是沒有使用savechange() |
Added | 新添加。對象已經添加到上下文,但沒有使用但是沒有使用savechange() |
Detached | 游離態。對象存在,但不被上下文跟蹤 |
以我個人的理解,那么添加數據的過程應該為:
1.先添加一個新的對象,此時是狀態為Detached,和數據庫,上下文都沒關系;
2.采用上下文的Add()添加對象,對象已經添加到上下文,此時狀態為Added,但是沒有savechange(),數據庫中沒有該數據;
3.上下文的savechange(),即同步數據庫和上下文。此時該數據狀態為Unchanged,數據庫中有該數據;
4.若把對象的State改為Detached,則上下文中沒有該對象。不然,對象的State為Unchanged,存在於上下文中。
因此,我猜測是在UnitWork添加的時候,在上下文中依舊有數據對象,然后在對其操作時(我這里時刪除數據)導致不能更新數據。但是具體為什么會報錯,不是很理解,希望可以討論學習一下。