使用时进行更改时SubmitChanges()
,LINQ有时会因ChangeConflictException
错误消息Row not found or changed
而异常死机,并且没有任何指示具有冲突的行或具有冲突更改的字段,当另一个用户更改了该行中的某些数据时.
有没有办法确定哪一行存在冲突以及它们出现在哪些字段中,还有一种方法可以让LINQ忽略该问题并简单地提交数据吗?
此外,是否有人知道当行中的任何数据发生更改时,或者仅在LINQ尝试更改的字段中更改了数据时是否发生此异常?
这是一种查看冲突位置的方法(这是一个MSDN示例,因此您需要进行大量自定义):
try { db.SubmitChanges(ConflictMode.ContinueOnConflict); } catch (ChangeConflictException e) { Console.WriteLine("Optimistic concurrency error."); Console.WriteLine(e.Message); Console.ReadLine(); foreach (ObjectChangeConflict occ in db.ChangeConflicts) { MetaTable metatable = db.Mapping.GetTable(occ.Object.GetType()); Customer entityInConflict = (Customer)occ.Object; Console.WriteLine("Table name: {0}", metatable.TableName); Console.Write("Customer ID: "); Console.WriteLine(entityInConflict.CustomerID); foreach (MemberChangeConflict mcc in occ.MemberConflicts) { object currVal = mcc.CurrentValue; object origVal = mcc.OriginalValue; object databaseVal = mcc.DatabaseValue; MemberInfo mi = mcc.Member; Console.WriteLine("Member: {0}", mi.Name); Console.WriteLine("current value: {0}", currVal); Console.WriteLine("original value: {0}", origVal); Console.WriteLine("database value: {0}", databaseVal); } } }
无论如何要使它忽略问题并提交:
db.SubmitChanges(ConflictMode.ContinueOnConflict);
这些(您可以在您的datacontext的部分类中添加它们可能有助于您了解其工作原理:
public void SubmitKeepChanges() { try { this.SubmitChanges(ConflictMode.ContinueOnConflict); } catch (ChangeConflictException e) { foreach (ObjectChangeConflict occ in this.ChangeConflicts) { //Keep current values that have changed, //updates other values with database values occ.Resolve(RefreshMode.KeepChanges); } } } public void SubmitOverwrite() { try { this.SubmitChanges(ConflictMode.ContinueOnConflict); } catch (ChangeConflictException e) { foreach (ObjectChangeConflict occ in this.ChangeConflicts) { // All database values overwrite current values with //values from database occ.Resolve(RefreshMode.OverwriteCurrentValues); } } } public void SubmitKeepCurrent() { try { this.SubmitChanges(ConflictMode.ContinueOnConflict); } catch (ChangeConflictException e) { foreach (ObjectChangeConflict occ in this.ChangeConflicts) { //Swap the original values with the values retrieved from the database. No current value is modified occ.Resolve(RefreshMode.KeepCurrentValues); } } }