如何:通过与数据库值合并解决冲突
若要先对帐预期数据库值与实际数据库值之间的差异,再尝试重新提交更改,则可以使用 KeepChanges 将数据库值与当前客户端成员值合并。 有关详细信息,请参阅乐观并发:概述。
备注
在所有情况下,都会先通过从数据库中检索更新后的数据来刷新客户端上的记录。 此操作确保了下一次更新尝试将通过相同的并发检查。
示例
在本方案中,当 User1 尝试提交更改时将引发 ChangeConflictException 异常,原因是 User2 同时已更改了 Assistant 和 Department 列。 下表说明了这种情况。
状态 | Manager | Assistant | 部门 |
---|---|---|---|
原始数据库在被 User1 和 User2 查询时的状态。 | Alfreds | Maria | Sales |
User1 准备提交这些更改。 | Alfred | Marketing | |
User2 已经提交了这些更改。 | Mary | 服务 |
User1 决定通过将数据库值与当前客户端成员值合并来解决此冲突。 结果将是,数据库值仅在当前变更集也修改了该值时才会被覆盖。
User1 通过使用 KeepChanges 解决了此冲突后,数据库中的结果将如下表所示:
状态 | Manager | Assistant | 部门 |
---|---|---|---|
解决冲突后的新状态。 | Alfred (来自 User1) |
Mary (来自 User2) |
Marketing (来自 User1) |
下面的示例演示如何将数据库值与当前客户端成员值合并(除非此客户端也已经更改了该值)。 未对各个成员冲突进行检查或自定义处理。
try
{
db.SubmitChanges(ConflictMode.ContinueOnConflict);
}
catch (ChangeConflictException e)
{
Console.WriteLine(e.Message);
// Automerge database values for members that client
// has not modified.
foreach (ObjectChangeConflict occ in db.ChangeConflicts)
{
occ.Resolve(RefreshMode.KeepChanges);
}
}
// Submit succeeds on second try.
db.SubmitChanges(ConflictMode.FailOnFirstConflict);
Try
db.SubmitChanges(ConflictMode.ContinueOnConflict)
Catch ex As ChangeConflictException
Console.WriteLine(ex.Message)
For Each occ As ObjectChangeConflict In db.ChangeConflicts
' Automerge database values into current for members
' that client has not modified.
occ.Resolve(Data.Linq.RefreshMode.KeepChanges)
Next
End Try
' Submit succeeds on second try.
db.SubmitChanges(ConflictMode.FailOnFirstConflict)