2012-08-16 212 views
1

我無法更新當我更改我的表中的某個字段。實體框架更新

  • 數據庫==> mysql的
  • .NET框架==> 4.0
  • 平臺==> WPF應用程序

讓我一步一步講解

我的目標是更新表中已經存在的項目。

public bool SaveToVideoInfo(List<tblvideoinfo> vList,sbyte profilID) 
    { 
        foreach (tblvideoinfo _videoinfo in vList) 
      { 

       try 
       { 

       ent.AddTotblvideoinfo(_videoinfo); 
       ent.AddTotblprocess(CreateProcess(profilID,_videoinfo.VideoID)); 
       ent.SaveChanges(); 

       } 
       catch (UpdateException) 
       { 

        return UpdateToVideoInfo(_videoinfo); 
       }    
     } 

      return false;      
    } 

如果在表中存在已經項,我趕上這個例外,並打電話給我更新功能

public bool UpdateToVideoInfo(tblvideoinfo vInfo) 
    { 

     var updatingItem = (from a in ent.tblvideoinfo 
        where a.VideoID == vInfo.VideoID 
        select a).First(); 

     updatingItem.SearchKeywords = vInfo.SearchKeywords; 
     updatingItem.SearchTimeStamp = DateTime.Now; 

     return ent.SaveChanges() > 0; 

    } 

因爲如果在表中存在,我想改變一些領域如我上面寫的。一切都很好,直到運行ent.SaveChanges()

我檢查updatingItem已經改變了我設置的屬性(SearchKeywords,SearchTimeStamp)

但出現此錯誤,同時更新條目中出現

錯誤。詳情請參閱

內部異常下面是詳細介紹

at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter) 
    at System.Data.EntityClient.EntityAdapter.Update(IEntityStateManager entityCache) 
    at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options) 
    at System.Data.Objects.ObjectContext.SaveChanges() 
    at MyDbHelper.DBHelper.UpdateToVideoInfo(tblvideoinfo vInfo) 
    at MyDbHelper.DBHelper.SaveToVideoInfo(List`1 vList, SByte profilID) 
    at youtube.MainWindow.p_Drop_Event(Object sender, Object to) in C:\Users\xxxxxx....\...\MainWindow.xaml.cs:line 1125 
    at youtube.product.UserControl_MouseUp(Object sender, MouseButtonEventArgs e) in C:\Users\xxxxxx....\...\product.xaml.cs:line 239 
    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& handled) 
    at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) 
    at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& 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.LegacyInvokeImpl(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& msg) 
    at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame) 
    at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame) 
    at System.Windows.Threading.Dispatcher.Run() 
    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 youtube.App.Main() in C:\Users\xxxxxx....\...\Debug\App.g.cs: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.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
    at System.Threading.ThreadHelper.ThreadStart() 

這裏updatingItem

的詳細

here is detail of updatingItem

手段,

updatingItem.SearchKeywords = vInfo.SearchKeywords; 
    updatingItem.SearchTimeStamp = DateTime.Now; 

這些代碼是工作。

與此同時,VideoID是唯一在我的表然後我不能添加具有相同VideoID的項目。但我想更新它。我認爲更新問題來自這裏。

我不想使用sql命令。

我只是想更新表的兩個領域...

+0

什麼是內部異常的描述? – 2012-08-16 13:10:11

+0

我已經在那裏寫下「這裏是詳細信息」 – unbalanced 2012-08-16 13:11:06

+1

這是堆棧跟蹤不是說明 – 2012-08-16 13:17:22

回答

1

我的猜測是,當您在同一個上下文中再次調用SaveChanges時,它試圖插入重複插入操作並再次失敗。

在catch塊的開頭調用ent.AcceptAllChanges()可能會起作用。

也許處置上下文並創建另一個用於更新函數將是最簡單的選擇。否則,您將需要將ObjectStateEntry.State更改爲Unchanged您嘗試插入的兩個實體(videoinfo,進程)。

+0

thanx。 ent.AcceptAllChanges();它使刪除錯誤。但在這個時候,savechanges方法返回0,並在表中,沒有任何變化.. – unbalanced 2012-08-16 13:18:39

+0

你是否嘗試將該調用放置在catch塊的開始? – Omtara 2012-08-16 13:20:01

+0

不,我沒有:)但它的作品。你是偉大的:)非常感謝你:)我寫了它開始的catch塊和工作:) – unbalanced 2012-08-16 13:22:21

0

有沒有辦法來檢查,如果該項目是新的?您可以將id設置爲0值或其他值,以便您可以輕鬆查看該項目是否爲新項目。

如果這是不可能的,你可以在Id上使用SingleOrDefault來檢查實體是否存在。這樣你就可以避免updatexception並在一次調用中處理所有事情。根據這種情況下的數據庫例外情況,這不是一個很乾淨的解決方案

在一次調用中處理所有事情應該可以解決您的問題。

+0

我看到,但問題是我該如何更新這個項目?這是不可能的 ?在sql中,我會寫「update tblvideoinfo set SearchKeywords ='bla bla'and SearchTimeStamp ='bla bla'where videoID ='blabla ...'」 – unbalanced 2012-08-16 13:13:37

+0

加載一個項目並在ObjectContext範圍內修改它自動跟蹤更改。調用SaveChanges將生成更新Sql – 2012-08-16 13:19:16

+0

感謝您的關注。 @Omtara已經解決了這個問題。 – unbalanced 2012-08-16 13:28:00

1

嘗試調用

var updatingItem = (from a in ent.tblvideoinfo 
        where a.VideoID == vInfo.VideoID 
        select a).FirstOrDefault(); 

和你正在使用

updatingItem.SearchTimeStamp = DateTime.Now; 

使用該字段的數據類型相同(日期時間),你的數據庫不?

一個選項是處理ObjectContext.SavingChanges事件,它使您有機會在保存更改之前對實體執行驗證,甚至在必要時取消保存。通過這種方式,您可以確保在嘗試保存更改之前設置了任何不可爲空的屬性,並避免必須依賴異常處理。

+0

我已經可以保存項目。但如果項目表中有相同的videoid我不能更新它。但@Omtara解決了這個問題 – unbalanced 2012-08-16 13:23:45

+0

好的:).......... – 2012-08-16 13:24:54

+0

thanx的注意。我沒有updateitem的任何問題,因爲我提到這是很好的。但它沒關係,它不工作,沒有問題:)謝謝 – unbalanced 2012-08-16 13:26:04