我有一个Linq-to-SQL RIA服务和一个silverlight客户端。当2个人编辑同一个实体时,我在调用SubmitChanges时在OnSubmitCompleted中收到EntityConflict。 现在我想对它做出反应而不会让用户太烦恼,我只想给他看一个消息框,让他知道数据已被修改,他的更改将被服务器值覆盖。
MyDomainContext.SubmitChanges(this.OnSubmitCompleted, invokeAfterSubmit);
private void OnSubmitCompleted(SubmitOperation so)
{
if (so.HasError)
{
if (so.EntitiesInError.Any(entity => entity.EntityConflict != null))
{
MessageBox.Show("Data has changed, entities will be reloaded....","Error", MessageBoxButton.OK);
// cache the entities, because the AcceptChanges() will clear them
var errorEntities = so.EntitiesInError.ToList();
// overwrite the local changes with the ones from the stoe
((IChangeTracking)Context.EntityContainer).AcceptChanges();
// reload the data
-> here comes the dirty code from below
// mark as handled as in "The User has been informed that all his stuff has been reverted"
so.MarkErrorAsHandled();
}
}
我不知道如何为这个特定实体重新加载数据。我甚至不介意再次重新加载整个数据。
目前我正在这样做,我觉得很脏:)
foreach (Entity entity in errorEntities)
{
var methodInfo = (from method in Context.GetType().GetMethods()
where method.Name.Contains("Query")
where method.Name.Contains(entity.GetType().Name)
select method);
foreach (var info in methodInfo)
{
// get the query from the Context to reload the entity
var result = (EntityQuery) info.Invoke(Context, null);
// load the entities
Context.Load(result, LoadBehavior.RefreshCurrent, null, null);
}
}
这有效,但我确信有更好的方法来解决冲突。 (合并当然会很棒!)
请让我知道更好的方法来处理这种情况:)
答案 0 :(得分:4)
可以在服务器上解决冲突的这个问题。域服务是一个部分类,您可以在其中覆盖方法ResolveConflicts
。
示例:
protected override bool ResolveConflicts(ChangeConflictCollection conflicts)
{
bool resolveChangeSetSuccess = true;
foreach (ObjectChangeConflict objectChangeConflict in conflicts)
{
foreach (MemberChangeConflict memberChangeConflict in objectChangeConflict.MemberConflicts)
{
if (memberChangeConflict.Member.Name == "Name of DB field")
{
memberChangeConflict.Resolve(RefreshMode.KeepCurrentValues);
}
else
{
memberChangeConflict.Resolve(RefreshMode.KeepChanges);
}
}
resolveChangeSetSuccess = resolveChangeSetSuccess && objectChangeConflict.IsResolved;
}
if (resolveChangeSetSuccess)
{
this.DataContext.SubmitChanges();
}
return resolveChangeSetSuccess;
}