2009-04-30 68 views
51

我想刪除使用LINQ(無 的LinqDataSource)選定gridview的行。System.Data.Linq.ChangeConflictException:未找到行或更改

當選擇改變時,在DetailsView結合被改變 也。我可以在新的條目添加到數據庫中,但是當我加入這個 代碼的UpdatePanel內刪除按鈕,我得到了一個例外:

try 
{   
    var query = from i in db.QuestionModules 
       where i.QuestionModuleID == QuestionModuleID 
       select i; 

    QuestionModule o = query.First(); 
    db.QuestionModules.DeleteOnSubmit(o); 
    db.SubmitChanges(); 
} 

這是例外,我得到:

System.Data.Linq.ChangeConflictException: Row not found or changed. at 
System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode 
failureMode) at 
System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode) 
at System.Data.Linq.DataContext.SubmitChanges() 

我有這個問題已經有一個星期了,不管我做什麼,它仍然是 ,並且記錄不會被刪除。

關於該怎麼做的任何想法?

回答

15

我有同樣的問題,和整個this blog,基本上說的LINQ到SQL得到了一個問題,這也正是樂觀併發來了:用於

  1. 高精度日期時間字段。解決的辦法是設置UpdateCheck的永不該列的DBML文件
  2. 被設置爲不可見的數據對象的訪問屬性(這第二個原因是沒有意義的,但它似乎是所有上風靡一時的GridView列博客)。

我還沒有嘗試過這些解決方案,但是一旦有了,我會回到這裏。

+0

好的 - 我剛剛嘗試將所有Date列的UpdateCheck設置爲Never ...沒有快樂,我仍然得到相同的結果。 – Mark 2009-07-06 13:23:21

+0

我有一些日期時間字段更新相同的問題:更改UpdateCheck值解決了問題。 – 2011-06-05 10:18:44

+2

+1我有這個問題,SQL數據庫上有一個`float`字段,我已經將它映射到C#中的`float`(single)類型。當我將類型改爲「雙」時,問題就消失了。但是你的這個答案引發了我的關注 - 所以謝謝! – 2011-06-06 15:03:55

66

確定 - 它看起來好像(在我的情況下,至少)的答案是所有非主鍵列的UpdateCheck的屬性設置爲決不在DBML文件。這樣做立即解決了「找不到或更改行」的問題。

鑑於傳聞,微軟是蛾泥包支持實體框架的LINQ到SQL中,無論是這些類型的錯誤都將被固定人們不禁要問?

+1

這可能有效,但天哪,這是可取的嗎?不適合我! – 2012-11-01 18:05:38

+0

+1,因爲它的工作。任何人都可以流下。有關這方面的影響的一些信息。博客文章或以其他方式將是偉大的。謝謝。 – Kieran 2012-11-22 03:51:20

0

下:

QuestionModule o = query.First(); 

你必須添加下面的命令:

db.QuestionModule.Attach(o); 
1

確保沒有列包含相關表null值(即表進行更新)。

0

我能夠回發的UpdatePanel期間執行數據綁定()在GridView和數據源來解決這個問題。

protected void UpdatePanel1_Load(object sender, EventArgs e) 
    { 
     GridView1.DataBind(); 
     LinqDataSource1.DataBind(); 
    } 

我每次刷新updatepanel時,我的選擇索引發生變化,它能夠解決衝突。

希望這會有所幫助。

6

似乎也適用於我的情況。我在內存中建立一個從未提交過的行,這個行與其他表中的行有幾個外鍵關係。InsertOnSubmit似乎工作,但隨後DeleteOnSubmit給我那行未發現錯誤。我沒有填充我提交的行中的每個字段,所以我不知道這與它有什麼關係,但標記了所有主表的非主鍵列都消除了錯誤消息。

一個進一步的思考:我是否可以認爲標誌着一個列的UpdateCheck的政策爲「從不」意味着不作爲樂觀併發性檢查的基礎。這意味着兩個用戶可以在任何這樣的列中使用不同的數據在給定的行上進行編寫,並且不會檢測到衝突......這意味着提交行的最後一個用戶將覆蓋先前用戶提交的值。我從各種在線閱讀中收集到一個解決方案,即在提交之前立即使用刷新方法來同步所有更改。當然,對行不加鎖定,不保證該行在刷新和提交之間不會改變,但在涉及大型數據庫的大多數情況下,這種情況很少發生。

更新:在進一步審查,我想我已經發現了,所以我想我會爲了以防萬一分享可能會影響其他人的情況。事實證明,使用SQL LINQ至少有一部分問題與觸發器有關。看起來,如果您使用SQL LINQ提交一行,並且您的DBA具有旨在將信息寫入該行中某些列的觸發器,那麼SQL LINQ模型將默認爲「始終」,以確定該行自上次寫入以來已更改。我提交了部分填充的行,而我們的DBA的觸發器填充了一些列,因此當我試圖進一步修改代碼中的行時,它會根據觸發器填充的列感知到更改衝突。我現在正在調查處理這個問題的最好方法,但將這些觸發器填充的字段更改爲使用「更改時間」或「從不」的UpdateCheck策略爲我工作。希望能幫助到你。

2

我在更新行時發生了類似的changeconflictexception /「Row not found or changed」行。 通過在dbml中重新添加tabbles來解決它。

12

問題可能還僅僅是表的DBML定義不與數據庫定義的狀態一致。我剛剛刪除了DBML模型並將其從數據庫中再次插入,並且它工作正常。

希望這有助於某人。

46

你很可能得到這個錯誤,因爲你的領域之一,在LINQ的不同的東西to SQL設計,並在實際的數據庫。

在我的情況,這是因爲該領域之一是在數據庫中可空,並在設計師不能爲空,使得它在和亟待解決的問題設計爲空。

0

另外 - 如果您要調用linqdatasource的選擇方法並手動設置e.result,請確保您也包含任何外鍵值。

沒有別的爲我工作,但這。

0

我固定它的方式是:首先,我更新數據庫,然後我設置爲網格的新值

e.Keys["ColumnOne"] ="new value" 
e.Keys["ColumnTwo"] ="new value" 

這一切的GridView_RowUpdating事件下完成的。

0

我只是想爲任何可能有此問題的人添加我的場景。

我們對我們的Linq to SQL dbml使用自定義T4。我們基本上只是修改了原來的get/set字符串屬性來自動修剪和設置null。

 get { return _OfficiantNameMiddle.GetValueOrNull(); } 
     set 
     { 
      value = value.GetValueOrNull(); 
      if (_OfficiantNameMiddle != value) 
      { 
       _IsDirty = true; 
       OnOfficiantNameMiddleChanging(value); 
       SendPropertyChanging("OfficiantNameMiddle"); 
       _OfficiantNameMiddle = value; 
       SendPropertyChanged("OfficiantNameMiddle"); 
       OnOfficiantNameMiddleChanged(); 
      } 
     } 

在我們的數據庫中遺留數據有一些前/後間隔等等這些列的任何併發檢查失敗,導致在比賽(這是比較對非修剪數據庫值的修整值)。對SQL進行概要分析非常簡單,只需在併發檢查期間開始返回一行,即可獲取SQL並開始註釋WHERE子句中的項目。

幸運的是,我們的表中有一個LastUpdatedOn字段,通過OnValidate(System.Data.Linq.ChangeAction)自動設置。

partial void OnValidate(System.Data.Linq.ChangeAction action) 
    { 
     if (action == System.Data.Linq.ChangeAction.Insert) 
     { 
      CreatedBy = CurrentUserID; 
      CreatedOn = DateTime.Now; 
      LastUpdatedBy = CreatedBy; 
      LastUpdatedOn = CreatedOn; 
     } 
     else if (action == System.Data.Linq.ChangeAction.Update) 
     { 
      LastUpdatedBy = CurrentUserID; 
      LastUpdatedOn = DateTime.Now; 
     } 
    } 

爲了繞過這個問題,我們只需設置併發檢查,不要在所有列,除了主鍵列和LastUpdatedOn列。這對我們有效。

0

我有一個類似的問題,雖然刪除和重新添加DBML表/類幫助一些用戶,對我來說有點不同,因爲我在客戶端使用WCF與分離的實體和ListView。

如果我用了.Attach(實體)失敗 - 「未找到行或更改」 但在使用時.Attach(實體,原件)它屢試不爽

public void DeleteTask(Task task) 
    { 
     TwoDooDataContext db = new TwoDooDataContext(); 
     db.Tasks.Attach(task,GetTaskByID(task.ID)); 
     db.Tasks.DeleteOnSubmit(task); 
     db.SubmitChanges(); 
    } 
0

對我來說是一個引起問題的enum列(映射到varchar),所以我不得不通過更新檢查。

8

我解決了這個問題,確保在更新之前立即刷新對象。我使用KeepChanges選項執行此操作。

db.Refresh(System.Data.Linq.RefreshMode.KeepChanges, employee); 
2

我的問題是,我在.NET Framework中一個DateTime類型,但我們的數據庫字段是DATETIME2類型,這是更高的精度數據類型。因此,當我們提交更改時,對象的數據字段與數據庫的距離僅爲幾納秒,這會導致併發錯誤。當我們遷移到一個更新的MSSQL版本並將DateTime字段轉換爲DateTime2時,就發生了這種情況。

在我們的代碼,我們不得不

所以:

Obj.DateUpdated = DateTime.Now() 

我們把它改爲:

Obj.DateUpdated = DateTime.Parse(DateTime.Now.ToString()) 

因此,檢查你的數據類型,尤其是你的日期字段,如果你做一個升級後出現此錯誤和/或遷移。

3

這只是一個不匹配列定義的例子。只需從.dbml中刪除表格並重新添加即可。確保爲具有自動生成數據的列(如主鍵或日期時間列)更改auto generate value property = true

0

正如@ dherrin79指出的,這可能是由於數據庫和代碼之間的精度差異造成的。對我來說,問題是數據庫列應該是十進制(10,2),但是它已經被創建爲十進制(18,0)。這是爲了金錢領域,所以也許我應該使用錢列類型。

所以,我節省了一美元的金額,如3.14美元,但小數點被剝離。這導致數據庫值被更改並且不匹配C#中的值。

希望這會有所幫助。

相關問題