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

发布于 2024-09-24 05:03:52 字数 3233 浏览 6 评论 0原文

我在 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 服务加载对象才能保存,我是否可以通过这种方式添加子对象?我是否应该以某种方式将域数据源从订单详细信息页面传递到子控件以获得一个数据源?或者我是否必须恢复在代码中进行克隆才能获取新对象?

I've got an order details form in Silverlight that has a listbox of order payments. The order payments are bound to their own domain datasource outside of the surrounding order. I have a button that pops up a ChildWindow control to add new order payments. An order payment has an amount and a payment method associated with it.

The form loads fine, displays all payment methods in a dataform in a dropdown along with the textbox for the amount. When I save the order payment and try to attach it back to the order details Order Payments datasource, I get the dreaded 'Entity cannot be attached because it is already attached to another entity' error.

Here's the XAML for the Add Order Payment child window:

<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>

Here's the code behind for the Add Order Payment screen:

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

Finally, here is the code that tries to reattach the new order payment to the order details screen:

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

Am I running into this problem because the Order Payment has a property on it that is bound to a different data context? Can I even add a child object in this way, given that the child object has to load objects from RIA services in order for it to be saved? Should I somehow pass the domaindatasource from the order details page to the child control to have one datasource? Or do I have to revert to doing a clone in code to get a new object?

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

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

发布评论

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

评论(1

瞳孔里扚悲伤 2024-10-01 05:03:52

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

I'd recommend you pass the DomainContext from the parent window (the one you use in add_Closed) to the child window and then use that DomainContext in your DomainDataSource (paymentMethodsSource). That way all the entities are being loaded into the same context. An alternate approach would be to do the query (GetPaymentMethods) in the parent window, pass the context to the child window, and just bind the ListBox.ItemsSource to CPSDomainContext.PaymentMethods in your child window.

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