DomainContext中的冲突处理

发布于 2024-11-02 08:53:01 字数 1732 浏览 3 评论 0原文

我有一个 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);
     }

   }

这可行,但我确信有更好的方法来解决冲突。 (合并当然很棒!)

请让我知道处理这种情况的更好方法:)

I have a Linq-to-SQL RIA service and a silverlight client. When 2 people edit the same entity I receive an EntityConflict in the OnSubmitCompleted when calling SubmitChanges.
Now I want to react to it without annoying the user too much, I only want to show him a message box and let him know that the data has been modified and that his changes will be overridden with the server values.

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();
  }
 }

I have no idea how to reload the data for this specific entity. I would not even mind reloading that whole data again.

At the moment I am doing this, and I feel very dirty :)

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);
     }

   }

This works, but I am sure there are better ways to resolve conflicts. (Merging would of course be great!)

Please let me know of better ways to handle this scenario :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不离久伴 2024-11-09 08:53:01

这个冲突问题可以在服务器上解决。域服务是一个分部类,您可以在其中重写方法 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;
}

This problem with the conflicts can be solved on the server. The domain service is a partial class where you can override the method ResolveConflicts.

Example:

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文