无法在一对多关系下删除表

时间:2016-02-08 18:03:33

标签: c# winforms entity-framework entity-framework-6

我有以下3个相关表格: enter image description here

我有一张表格。假设它被称为fmEditPurchase。在该表单中,我可以编辑Purchase个信息,并添加/删除PurchasedProductenter image description here

该格式可能会有很多变化,但只有点击保存按钮才能应用更改,该按钮会将DialogResult.OK返回到父窗体。下面的方法位于主窗体中。

    private void Purchase_EditPurchase(object sender, DataGridViewCellEventArgs e)
    {
        if (dgvPurchase.SelectedRows.Count == 1)
        {
            int index = dgvPurchase.SelectedCells[0].RowIndex;
            DataGridViewRow selectedRow = dgvPurchase.Rows[index];

            int id = (int)selectedRow.Cells["ID"].Value;

            Purchase edit = null;

            using (var context = new dbKrunchworkContext())
            {
                edit = context.Purchases.Where(x => x.ID == id).FirstOrDefault();

                if (edit != null)
                {
                    fmAddEditPurchase editForm = new fmAddEditPurchase(edit);

                    if (editForm.ShowDialog() == DialogResult.OK)
                    {
                        //Section 1
                        foreach (var item in editForm.DeletedPP)
                        {
                            context.Entry(item).State = EntityState.Deleted;
                            context.Entry(item.Product).State = EntityState.Unchanged;
                        }

                        //Section 2
                        context.Entry(editForm.Purchase).State = EntityState.Modified;

                        //Section 3
                        foreach (var item in editForm.Purchase.PurchasedProducts)
                        {
                            context.Entry(item.Product).State = EntityState.Unchanged;
                        }

                        tslbMessage.Text =
                            string.Format("Product Data Edited");

                        context.SaveChanges();
                        Purchase_RefreshDGVPurchase();
                    }
                }
            }
        }
    }

因此,总而言之,特定Purchase记录的更改可以包括删除/添加PurchasedProduct以及其他所有字段,在按下“保存”按钮后,将会应用所有字段。< / p>

问题是,当我正在编辑,删除PurchasedProduct并保存时,会弹出以下错误。

enter image description here

即使我重新排列第1,2和3部分的顺序,问题仍然存在(请查看顶部代码以查看注释中标记的1,2,3部分。)

我也无法执行SaveChanges()中的fmEditPurchase,因为它可以被取消以进行0次更改。

如何解决?感谢

2 个答案:

答案 0 :(得分:0)

根据你的评论:

  

购买记录不能包含2张带有相同记录的PurchasedProduct记录   产品(只需添加数量instea)

您不需要将PK设置为Product_ID。 FK应该足够了。如果您想增加数量,只需查找Product_ID的搜索记录,请更新并保存。这样就可以删除。

答案 1 :(得分:0)

最后解决了这个问题,而Rodolfo的回答有助于解决方案,但这还不够。

这就是我所做的:

  1. 我将数据库上下文作为参数添加到编辑对话框构造函数中,还有一个用于存储上下文的字段。

    private dbKrunchworkContext context;
    public fmAddEditPurchase(dbKrunchworkContext context)
    {
        //Bla bla
        this.context = context;
        //Bla bla
    }
    
  2. 在我初始化之前&amp;显示对话框,我使用using(var context = new dbKrunchworkContext) { }初始化上下文并将值传递给对话框。

    using (var context = new dbKrunchworkContext())
    {
        edit = context.Purchases.Where(x => x.ID == id).FirstOrDefault();
    
        if (edit != null)
        {
            fmAddEditPurchase editForm = new fmAddEditPurchase(context, edit);
    
            if (editForm.ShowDialog() == DialogResult.OK)
            {
                //Blabla
            }
        }
    }
    
  3. 在新对话框中,每次我要使用上下文时,我都使用上下文字段而不是使用新实例化的字段。

    private void RefreshPurchasedProduct()
    {
        BindingSource bi = new BindingSource();
    
        //Bla bla
    
        bi.DataSource = Purchase.PurchasedProducts.
            Join(context.Products, x => x.Product.ID, y => y.ID, (x, y) =>
                new { y.Product_Name, x.Price, x.Quantity }).ToList();
    
        //Bla bla
    }
    
  4. 这样,就没有(恼人的)The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects.

    希望这有助于任何人偶然发现我的这个类似问题。

    P.S。有些解决方案可能更喜欢用静态上下文解决它,从来没有尝试过,但是如果我,我更喜欢这种方式,因为它会更干净,维护更少的代码。