2013-12-17 14 views
1

當我第一次保存一個實體對象時,它可以很好地工作,但是在同一對象上進行第二次嘗試時,它會失敗,出現DbUpdateConcurrencyException。 我已經設置Concurrency ModeFixed在「LastUpdated」屬性上,這是一個DateTime,並且只有應用程序正在運行時才維護上下文的一個實例。保存兩次時拋出DbUpdateConcurrencyException

之前救了我的對象我自動更新「併發」(DatMaj)的財產,這是我的保存方法(這是一個簡化版本,但它仍然崩潰):

public virtual bool Save(IDbEntity pEntityToSave) 
    { 
     pEntityToSave.DatMaj = DateTime.Now; 
     var result = ContextManager.Context.SaveChanges(); 

     //With this the DbUpdateConcurrencyException problem disappears, but it is a unnecessary hit to the database. 
     //if (result > 0) 
     // Reload(pEntityToSave); 

     return (result > 0); 
    } 

它工作得很好的第一次。 但是如果我編輯它並在幾秒鐘後再次保存,則會拋出DbUpdateConcurrencyException

什麼是真正奇怪的是,如果我登錄由實體框架生成的SQL,在第二次嘗試,我看到:

UPDATE [flux].[EXO_PTN_Partenaire] 
SET [PTN_DatMaj] = @0 
WHERE (([PTN_IdPartenaire] = @1) AND ([PTN_DatMaj] = @2)) 

-- @0: '17/12/2013 18:04:20' (Type = DateTime2) 

-- @1: '2' (Type = Int64) 

-- @2: '17/12/2013 18:04:03' (Type = DateTime2) 

-- Executing at 17/12/2013 18:04:20 +01:00 

-- Completed in 1 ms with result: 0 

正如你所看到的,它說:Completed in 1 ms with result: 0,但如果我執行完全相同的直接在數據庫上手動查詢,它工作。

如果在try...catch...我打電話ex.Entries.Single().Reload();並保存再次,它的工作原理,並記錄與完全相同相同的篩選器的SQL查詢。 我不知道爲什麼它似乎無法執行(我懷疑它沒有真正執行它),而我可以做到這一點。
我錯過了什麼嗎?這是一種緩存問題嗎?我認爲實體框架在保存後重置對象狀態(狀態,原始值...),但可能不完全。

解決此問題的一個簡單解決方法是在SaveChanges()之後使用Reload(),但我認爲這對數據庫是無用的命中。是否有另一種解決方法?

我使用C#4.0(WPF),與實體框架6(的DbContext),在SQL Server 2008 R2數據庫

更新於:根據要求,堆棧跟蹤

System.Transactions Critical: 0 : <TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Critical"><TraceIdentifier>http://msdn.microsoft.com/TraceCodes/System/ActivityTracing/2004/07/Reliability/Exception/Unhandled</TraceIdentifier><Description>Unhandled exception</Description><AppDomain>PS.vshost.exe</AppDomain><Exception><ExceptionType>System.Data.Entity.Infrastructure.DbUpdateConcurrencyException, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType><Message>Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.</Message><StackTrace> at System.Data.Entity.Internal.InternalContext.SaveChanges() 
    at System.Data.Entity.Internal.LazyInternalContext.SaveChanges() 
    at System.Data.Entity.DbContext.SaveChanges() 
    at ...DS.BaseDS`1.Save(IDbEntity pEntityToSave) in ...:line 38 
    at ...BS.BaseBS`1.Save(TEntity pEntity) in ...:line 26 
    at ...PS.ViewModel.BaseViewModel`2.SaveCurrentEntity() in ...:line 129 
    at ...PS.ViewModel.FileViewModel.Enregistrer_Execute() in...:line 69 
    at ...PS.ViewModel.FileViewModel.&amp;lt;InitializeCommands&amp;gt;b__6(Object x) in ...:line 51 
    at ...WPF.DelegateCommand.Execute(Object parameter) in ...:line 84 
    at MS.Internal.Commands.CommandHelpers.CriticalExecuteCommandSource(ICommandSource commandSource, Boolean userInitiated) 
    at System.Windows.Controls.Primitives.ButtonBase.OnClick() 
    at System.Windows.Controls.Button.OnClick() 
    at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e) 
    at System.Windows.UIElement.OnMouseLeftButtonUpThunk(Object sender, MouseButtonEventArgs e) 
    at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget) 
    at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) 
    at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) 
    at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) 
    at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent) 
    at System.Windows.UIElement.OnMouseUpThunk(Object sender, MouseButtonEventArgs e) 
    at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget) 
    at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) 
    at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) 
    at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) 
    at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args) 
    at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args) 
    at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted) 
    at System.Windows.Input.InputManager.ProcessStagingArea() 
    at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input) 
    at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport) 
    at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel) 
    at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean&amp;amp; handled) 
    at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean&amp;amp; handled) 
    at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean&amp;amp; handled) 
    at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) 
    at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) 
    at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler) 
    at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs) 
    at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam) 
    at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG&amp;amp; msg) 
    at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame) 
    at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame) 
    at System.Windows.Application.RunDispatcher(Object ignore) 
    at System.Windows.Application.RunInternal(Window window) 
    at System.Windows.Application.Run(Window window) 
    at System.Windows.Application.Run() 
    at ...PS.App.Main() in ...:line 0 
    at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) 
    at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 
    at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
    at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
    at System.Threading.ThreadHelper.ThreadStart()</StackTrace><ExceptionString>System.Data.Entity.Infrastructure.DbUpdateConcurrencyException: Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries. ---&amp;gt; System.Data.Entity.Core.OptimisticConcurrencyException: Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries. 
    at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.ValidateRowsAffected(Int64 rowsAffected, UpdateCommand source) 
    at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update() 
    at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.&amp;lt;Update&amp;gt;b__2(UpdateTranslator ut) 
    at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update[T](T noChangesResult, Func`2 updateFunction, Boolean throwOnClosedConnection) 
    at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update(Boolean throwOnClosedConnection) 
    at System.Data.Entity.Core.Objects.ObjectContext.&amp;lt;SaveChangesToStore&amp;gt;b__b() 
    at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess) 
    at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions options, IDbExecutionStrategy executionStrategy) 
    at System.Data.Entity.Core.Objects.ObjectContext.&amp;lt;&amp;gt;c__DisplayClass9.&amp;lt;SaveChanges&amp;gt;b__6() 
    at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation) 
    at System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(SaveOptions options) 
    at System.Data.Entity.Internal.InternalContext.SaveChanges() 
    --- End of inner exception stack trace --- 
    at System.Data.Entity.Internal.InternalContext.SaveChanges() 
    at System.Data.Entity.Internal.LazyInternalContext.SaveChanges() 
    at System.Data.Entity.DbContext.SaveChanges() 
    at ...DS.BaseDS`1.Save(IDbEntity pEntityToSave) in ...:line 38 
    at ...BS.BaseBS`1.Save(TEntity pEntity) in ...:line 26 
    at ...PS.ViewModel.BaseViewModel`2.SaveCurrentEntity() in ...:line 129 
    at ...PS.ViewModel.FileViewModel.Enregistrer_Execute() in ...:line 69 
    at ...PS.ViewModel.FileViewModel.&amp;lt;InitializeCommands&amp;gt;b__6(Object x) in ...:line 51 
    at ...WPF.DelegateCommand.Execute(Object parameter) in...:line 84 
    at MS.Internal.Commands.CommandHelpers.CriticalExecuteCommandSource(ICommandSource commandSource, Boolean userInitiated) 
    at System.Windows.Controls.Primitives.ButtonBase.OnClick() 
    at System.Windows.Controls.Button.OnClick() 
    at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e) 
    at System.Windows.UIElement.OnMouseLeftButtonUpThunk(Object sender, MouseButtonEventArgs e) 
    at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget) 
    at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) 
    at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) 
    at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) 
    at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent) 
    at System.Windows.UIElement.OnMouseUpThunk(Object sender, MouseButtonEventArgs e) 
    at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget) 
    at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) 
    at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) 
    at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) 
    at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args) 
    at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args) 
    at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted) 
    at System.Windows.Input.InputManager.ProcessStagingArea() 
    at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input) 
    at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport) 
    at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel) 
    at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean&amp;amp; handled) 
    at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean&amp;amp; handled) 
    at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean&amp;amp; handled) 
    at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) 
    at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) 
    at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler) 
    at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs) 
    at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam) 
    at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG&amp;amp; msg) 
    at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame) 
    at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame) 
    at System.Windows.Application.RunDispatcher(Object ignore) 
    at System.Windows.Application.RunInternal(Window window) 
    at System.Windows.Application.Run(Window window) 
    at System.Windows.Application.Run() 
    at ...PS.App.Main() in ...:line 0 
    at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) 
    at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 
    at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
    at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
    at System.Threading.ThreadHelper.ThreadStart()</ExceptionString><DataItems><Data></Data></DataItems><InnerException><ExceptionType>System.Data.Entity.Core.OptimisticConcurrencyException, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType><Message>Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.</Message><StackTrace> at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.ValidateRowsAffected(Int64 rowsAffected, UpdateCommand source) 
    at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update() 
    at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.&amp;lt;Update&amp;gt;b__2(UpdateTranslator ut) 
    at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update[T](T noChangesResult, Func`2 updateFunction, Boolean throwOnClosedConnection) 
    at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update(Boolean throwOnClosedConnection) 
    at System.Data.Entity.Core.Objects.ObjectContext.&amp;lt;SaveChangesToStore&amp;gt;b__b() 
    at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess) 
    at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions options, IDbExecutionStrategy executionStrategy) 
    at System.Data.Entity.Core.Objects.ObjectContext.&amp;lt;&amp;gt;c__DisplayClass9.&amp;lt;SaveChanges&amp;gt;b__6() 
    at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation) 
    at System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(SaveOptions options) 
    at System.Data.Entity.Internal.InternalContext.SaveChanges()</StackTrace><ExceptionString>System.Data.Entity.Core.OptimisticConcurrencyException: Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries. 
    at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.ValidateRowsAffected(Int64 rowsAffected, UpdateCommand source) 
    at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update() 
    at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.&amp;lt;Update&amp;gt;b__2(UpdateTranslator ut) 
    at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update[T](T noChangesResult, Func`2 updateFunction, Boolean throwOnClosedConnection) 
    at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update(Boolean throwOnClosedConnection) 
    at System.Data.Entity.Core.Objects.ObjectContext.&amp;lt;SaveChangesToStore&amp;gt;b__b() 
    at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess) 
    at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions options, IDbExecutionStrategy executionStrategy) 
    at System.Data.Entity.Core.Objects.ObjectContext.&amp;lt;&amp;gt;c__DisplayClass9.&amp;lt;SaveChanges&amp;gt;b__6() 
    at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation) 
    at System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(SaveOptions options) 
    at System.Data.Entity.Internal.InternalContext.SaveChanges()</ExceptionString></InnerException></Exception></TraceRecord> 

回答

1

不當然,但如果你將它添加到修改實體兩次:

if (pEntityToUpdate != null) 
    modifiedEntities.Add(pEntityToUpdate); 

..我會期待一些問題。它看起來像'如果'應該測試別的東西。該實體是否有IDENITY列?如果是這樣,那麼測試應該反對這個設定。

乾杯 -

+0

modifiedEntities只是爲了申請之日起變化的臨時變量。該項目不會被添加到該列表兩次。該方法採用一個實體或沒有一個。如果一個實體,它意味着我想強制這個項目被更新(所以即使用戶沒有改變任何東西,我希望它被標記爲已修改,如果我更改日期會發生這種情況),如果沒有,所有必須更新將被保存的實體。可以肯定的是,我試着刪除這段代碼,只保留日期更新,但並沒有改變任何內容。 –

+0

好的,我現在明白了。由於SQL正在生成OK,因此它在EF完成後調整內部狀態時變得越來越難過。重新加載實體修復它,然後保存起作用,是嗎?只是一個猜測,但它可能是值得讓實體模型重新生成代碼 –

+0

是的,重新加載工程。所以這不是一個關鍵問題,只是重新加載剛剛保存的完全相同的數據而煩人。這是一個不必要的查詢。當我在模式上工作時,我經常重新生成代碼,問題總是在那裏:(。 –

相關問題