C# 持续更新和调用submitchanges:此实体当前为只读ria服务

C# 持续更新和调用submitchanges:此实体当前为只读ria服务,c#,silverlight,silverlight-4.0,wcf-ria-services,C#,Silverlight,Silverlight 4.0,Wcf Ria Services,我正在制作一个Todo类型的应用程序,用户可以在其中做笔记,并在屏幕上不断移动笔记。每次更改“注意”的位置时,我都需要将其保存到数据库中: 这方面的典型代码是: private void SaveChanges() { if (!_context.IsSubmitting) { this.busyIndicator.IsBusy = true; _context.SubmitChanges(subOp =&

我正在制作一个Todo类型的应用程序,用户可以在其中做笔记,并在屏幕上不断移动笔记。每次更改“注意”的位置时,我都需要将其保存到数据库中:

这方面的典型代码是:

 private void SaveChanges()
    {
        if (!_context.IsSubmitting)
        {
            this.busyIndicator.IsBusy = true;
            _context.SubmitChanges(subOp =>
            {

                this.busyIndicator.IsBusy = false;
                if (subOp.Error != null)
                {
                    ErrorWindow window = new ErrorWindow(subOp.Error.Message);
                    window.Show();
                }

            }, null);
        }
    }
但是,正如您所看到的,我通过使用busyindicator阻止用户在提交时执行任何活动来阻止UI。这对该应用程序尤其不利。因此,作为替代方案,我尝试使用以下代码将此代码移动到另一个线程上:

    private void SaveChanges()
    {
        ThreadPool.QueueUserWorkItem(waitcall =>
        {
            if (!_context.IsSubmitting)
            {
                //this.busyIndicator.IsBusy = true;
                _context.SubmitChanges(subOp =>
                {
                    Dispatcher.BeginInvoke(() =>
                    {
                        //this.busyIndicator.IsBusy = false;
                        if (subOp.Error != null)
                        {
                            ErrorWindow window = new ErrorWindow(subOp.Error.Message);
                            window.Show();
                        }
                    });

                }, null);
            }

        });
    }
这是可行的,应用程序仍然保持响应速度。但是现在,当上下文提交更改,用户通过在屏幕上移动注释等方式处理相同注释时,绑定尝试更改实体的属性,我得到了一个异常:

此实体当前是只读的


我理解这是显而易见的,因为上下文正在提交更改。但是,是否有任何方法可以通过不显示dumb busy(哑忙)指示器来保持应用程序的响应,并且仍然不获取这些异常?

在提交更改期间,所有更改的属性都设置为只读。在您的情况下,它是位置属性。我猜这些属性是绑定到note位置的

可能性:

  • 不要绑定到域上下文中的实体。绑定到具有属性更改事件的客户端本地对象(可能是实体的克隆)。使用属性changed events尝试将更改复制到上下文实体。如果失败(只读),您可能希望添加代码以稍后重试

  • 使用EntityGraph从RIA Services Contrib部分提交。 riaservicescontrib.codeplex.com 检查讨论/博客-提供了将EntityGraph克隆到临时上下文并提交临时上下文的代码。我认为您不希望在完成时进行同步,因为这可能会覆盖新位置并导致窗口跳转。就这么顺其自然吧。 如果要在客户端上添加实体,并且需要从服务器返回自动生成的密钥属性(标识等)。然后,不要为添加使用临时上下文/部分提交。阻止UI并正常提交add,以便在完成时更新客户端属性,并且在设置键值之前不会调用部分提交


  • 我对任何其他可能的解决办法都感兴趣

    您还可以维护未完成提交操作数的线程安全计数,并在当前提交操作的回调中弹出下一个:

    public static int myPendingSubmitOperationsCount;
    ...
    myDataContext.SubmitChanges(mySubmitCallback, null);
    ...
    mySubmitCallback(SubmitOperation so)
    {
         //Do important stuff
         if(myPendingSubmitOperationsCount > 0)
         {
             myDataContext.SubmitChanges(mySubmitCallback, null);
             myPendingSubmitOperationsCount -= 1;
         }
    }
    

    你为什么对每一个变化都吝啬?为什么不等到用户停止更改后再提交?保存每次更改意味着“用户停止移动便笺”。当用户停止移动便笺时,我需要保存。通常情况下是这样的:1)用户“停止”移动便笺2)提交更改激发3)在提交更改期间,用户再次移动便笺并激发异常。听起来您的代码没有正确处理可重入性。。。你为什么不在第一次提交完成后再提交第二次修改呢?我想你不明白我的问题。“为什么不在第一次提交完成后提交第二次更改?”我如何知道第二次更改何时发生?用户不仅可以在便笺周围移动便笺2次,还可以在便笺周围移动N次。我怎么知道用户第n次移动完便笺并保存了更改:)?这不是我的意思:我不是说等到用户做了所有更改,不再做任何更改,只是推迟第二次/第三次等。
    submitchanges
    直到上一次的
    submitchanges
    完成了像您一样的执行解决。另一种解决方案是使用存储过程而不是调用SubmitChanges。