从子窗口添加实体导致实体无法附加错误....为什么?

时间:2010-09-16 16:27:56

标签: silverlight wcf-ria-services 2-way-object-databinding

我在Silverlight中有一个订单详细信息表单,其中包含订单付款列表框。订单付款绑定到周围订单之外的自己的域数据源。我有一个弹出ChildWindow控件的按钮来添加新的订单付款。订单付款具有与其相关联的金额和付款方式。

表单加载正常,在下拉列表中显示数据表单中的所有付款方式以及金额的文本框。当我保存订单付款并尝试将其附加到订单详细信息订单付款数据源时,我得到了可怕的“实体无法附加,因为它已经附加到另一个实体”错误。

以下是添加订单付款子窗口的XAML:

<controls:ChildWindow.Resources>
    <riaControls:DomainDataSource x:Key="paymentMethodsSource" QueryName="GetPaymentMethods" AutoLoad="True">
        <riaControls:DomainDataSource.DomainContext>
            <ds:CPSDomainContext />
        </riaControls:DomainDataSource.DomainContext>
    </riaControls:DomainDataSource>
</controls:ChildWindow.Resources>

<dataForm:DataForm x:Name="addOrderPaymentDataForm"  AutoGenerateFields="False" AutoCommit="True" AutoEdit="True" CommandButtonsVisibility="None">
        <dataForm:DataForm.EditTemplate>
            <DataTemplate>
                <StackPanel>


                    <dataForm:DataField Label="Payment Method">
                        <ListBox ItemsSource="{Binding Data, Source={StaticResource paymentMethodsSource}}" 
                                 DisplayMemberPath="Name"
                                 SelectedItem="{Binding PaymentMethod, Mode=TwoWay}"
                                 SelectionMode="Single"/>
                    </dataForm:DataField>

                    <dataForm:DataField Label="Amount">
                        <TextBox Text="{Binding Amount, Mode=TwoWay}" />
                    </dataForm:DataField>

                </StackPanel>
            </DataTemplate>
        </dataForm:DataForm.EditTemplate>
    </dataForm:DataForm>

以下是“添加订单付款”屏幕背后的代码:

public AddOrderPaymentWindow() {
        InitializeComponent();
        NewOrderPayment = new OrderPayment();
        addOrderPaymentDataForm.CurrentItem = NewOrderPayment;
        addOrderPaymentDataForm.BeginEdit();
    }

    public OrderPayment NewOrderPayment { get; set; }

    private void OKButton_Click(object sender, RoutedEventArgs e) {
        NewOrderPayment.CreatedBy = "jkandiko";
        NewOrderPayment.CreatedOn = DateTime.Now;
        NewOrderPayment.ModifiedBy = "jkandiko";
        NewOrderPayment.ModifiedOn = DateTime.Now;
        var result = addOrderPaymentDataForm.CommitEdit();
        this.DialogResult = true;
    }

    private void CancelButton_Click(object sender, RoutedEventArgs e) {
        NewOrderPayment = null;
        addOrderPaymentDataForm.CancelEdit();
        this.DialogResult = false;
    }

最后,以下是尝试将新订单付款重新附加到订单详情屏幕的代码:

 void add_Closed(object sender, EventArgs e) {
        AddOrderPaymentWindow pay = (AddOrderPaymentWindow)sender;
        if (pay.NewOrderPayment != null) {
            Administration.Web.Services.CPSDomainContext context = (CPSDomainContext)orderPaymentDataGridSource.DomainContext;

            context.OrderPayments.Add(pay.NewOrderPayment);
            context.SubmitChanges();
        }
    }

我是否遇到此问题,因为订单付款上有一个绑定到不同数据上下文的属性?我是否可以以这种方式添加子对象,因为子对象必须从RIA服务加载对象才能保存它?我应该以某种方式将domaindatasource从订单详细信息页面传递给子控件以获得一个数据源吗?或者我是否必须恢复在代码中进行克隆才能获得新对象?

1 个答案:

答案 0 :(得分:1)

我建议您将DomainContext从父窗口(您在add_Closed中使用的窗口)传递到子窗口,然后在DomainDataSource(paymentMethodsSource)中使用该DomainContext。这样,所有实体都被加载到相同的上下文中。另一种方法是在父窗口中执行查询(GetPaymentMethods),将上下文传递给子窗口,然后将ListBox.ItemsSource绑定到子窗口中的CPSDomainContext.PaymentMethods。