C# 实体框架-(主详细信息)如何更新与主详细信息分开的表单上的详细信息

C# 实体框架-(主详细信息)如何更新与主详细信息分开的表单上的详细信息,c#,winforms,entity-framework,C#,Winforms,Entity Framework,我正试图为我的项目做这件事 但是我用的不是单一的形式,而是两种形式 CategoryDataGridView显示在Form1上,然后在Form1上有一个编辑按钮,该按钮将加载包含ProductsDataGridView(所选类别的产品列表)和一个保存按钮以保存更改的Form2 我的表格2上有以下代码 ProductContext _context = new ProductContext(); public int SeletedCategID { get; set; } private vo

我正试图为我的项目做这件事 但是我用的不是单一的形式,而是两种形式

CategoryDataGridView
显示在
Form1
上,然后在
Form1
上有一个编辑按钮,该按钮将加载包含
ProductsDataGridView
(所选类别的产品列表)和一个保存按钮以保存更改的Form2

我的表格2上有以下代码

ProductContext _context = new ProductContext();
public int SeletedCategID { get; set; }

private void Form2_Load(object sender, EventArgs e)
{
    _context.Products.Where(c => c.CategoryId ==     SeletedCategID).ToList();
    productsBindingSource.DataSource =     (_context.Products.Local).ToList();
}

private void SaveBtn_Click(object sender, EventArgs e)
{
    this.Validate();

    foreach (var product in _context.Products.Local.ToList())
    {
        if (product.Category == null)
        {
            _context.Products.Remove(product);
        }
    }
    this._context.SaveChanges();

    this.productsDataGridView.Refresh();

    Form1 frm1 = (Form1)Application.OpenForms["Form1"];
    frm1.Activate();
    frm1.Refresh();
    this.Dispose();
}

我现在的问题是,只有对产品的编辑保存到数据库中。添加和删除未保存到数据库。

这无法工作,您必须删除产品,而不是本地

        foreach (var product in _context.Products.ToList())
        {
            if (product.Category == null)
            {
                _context.Products.Remove(product);
            }
        }
        this._context.SaveChanges();
如果只想删除本地文件,则:

_context.Locals.Remove(local);

我不知道您对加载对象列表做了什么,但是如果您试图更改或删除产品或在DbContext中找不到的本地实体,或者它是实体的副本,那么这将不起作用。您需要原始检索实体。

您应该将
context.Products.Local
设置为绑定源的数据源,同时设置
context.Products.Local.ToList()

context.Products.Local
获取一个
ObservableCollection
,它将与上下文保持同步,因此所有实体的更改(添加/删除/编辑)都将按上下文进行跟踪。
当您使用
context.Products.Local.ToList()
时,您使用的是一个
列表
,该列表不会与上下文保持同步,添加/删除不会被跟踪,调用
SaveChanges
时,您的添加和删除不会被保存,而编辑将被保存

获取表示所有对象的本地视图的
ObservableCollection
在此集合中添加、更改和修改实体。这是本地的观点 将在从上下文中添加或删除实体时保持同步。 同样,添加到本地视图或从本地视图中删除的实体也将 自动添加到上下文或从上下文中删除

代码:

您可以通过以下方式加载数据:

context.Products.Where(x => x.CategoryId == SelectedCategoryId).ToList();
this.productBindingSource.DataSource = context.Products.Local;
this.Validate();
this.productBindingSource.EndEdit();
context.Products.Local
       .Where(x => x.CategoryId == 0)
       .ToList().ForEach(x =>
       {
           x.CategoryId = SelectedCategoryId;
       });
context.SaveChanges();
this.DialogResult = DialogResult.OK;
您可以通过以下方式保存数据:

context.Products.Where(x => x.CategoryId == SelectedCategoryId).ToList();
this.productBindingSource.DataSource = context.Products.Local;
this.Validate();
this.productBindingSource.EndEdit();
context.Products.Local
       .Where(x => x.CategoryId == 0)
       .ToList().ForEach(x =>
       {
           x.CategoryId = SelectedCategoryId;
       });
context.SaveChanges();
this.DialogResult = DialogResult.OK;
您也不需要删除具有空类别的产品的代码部分,因为您不使用master detail。这是一个可编辑的列表


另一方面,在关闭第二个表单之后,不要忘记在第一个表单中重新加载数据。由于您在表单中使用了不同的上下文,因此他们不知道其他上下文中的更改。

您确定在
表单1
中会看到任何更改吗?我假设它有自己的上下文和自己的缓存实体。嗨,雷扎,谢谢你的详细回答。。但是,在尝试将
productBindingSource.DataSource
设置为
Products.Local
时,编辑和删除会保存到DB,但添加未保存到DB,并且还会显示一个
DataGridView默认错误对话框
错误。下面是消息:DataGridView中发生以下异常:System.IndexOutOfRangeException:索引3没有值。在System.Windows.Forms.CurrencyManager.get_项(Int32索引)在System.Windows.Forms.DataGridView.DataGridViewDataConnection.GetError(Int32 rowIndex)中显示7次。可能是因为您没有为新记录设置有效的
类别ID
。不要在网格中显示
CategoryId
列,而是在保存更改时,将所有产品的
CategoryId
设置为
SelectedCategoryId
。解决方案就是我说的。它经过测试并正常工作:)尝试了您的建议以删除categoryID列,也删除了CategoryName列,但如何在保存bro时将所有产品的类别设置为SelectedCategoryID?如果您未在模型中包含外键,请从edmx中删除模型,然后再次更新模型并包含外键。