c# - 错误 "An entity object cannot be referenced by multiple instances of IEntityChangeTracker"

标签 c# .net sql-server entity-framework ado.net

friend 。 我真的需要你的帮助。我将不胜感激。

所以我在 MS SQL Server 中有实体“Model”c 字段“ID_model”和“name”。 我希望在单击 Form1 上的“编辑”后,还有另一个表单 (FormModel),您可以在其中更改数据并将更改写入数据库。

问题是,在按下“编辑”后,出现关于“附加信息:一个实体对象不能被多个 IEntityChangeTracker 实例引用”的错误,我不知道如何修复它。

enter image description here

来自 Form1 的代码:

public partial class Form1 : Form
{
    MyDBEntities db2;
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        db2 = new MyDBEntities();
        modelBindingSource.DataSource = db2.Models.ToList();
        dataGridView.Columns.RemoveAt(2);
    }

    private void btnEdit_Click(object sender, EventArgs e)
    {
        if (modelBindingSource.Current == null)
            return;
        using (FormModel frm = new FormModel(modelBindingSource.Current as Model))
        {
            if (frm.ShowDialog() == DialogResult.OK)
            {
                modelBindingSource.DataSource = db2.Models.ToList();
            }
        }
    }
}

来自 FormModel 的代码:

public partial class FormModel : Form
{
    MyDBEntities db2;
    public FormModel(Model obj)
    {
        InitializeComponent();


        db2 = new MyDBEntities();
        if (obj == null)
        {
            modelBindingSource.DataSource = new Model();
            db2.Models.Add(modelBindingSource.Current as Model);
        }
        else
        {
            modelBindingSource.DataSource = obj;
            db2.Models.Attach(modelBindingSource.Current as Model);
        }
    }

    private void FormModel_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (DialogResult == DialogResult.OK)
        {
            if (string.IsNullOrEmpty(txtModelName.Text))
            {
                MessageBox.Show("There are empty fields", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Information);
                txtModelName.Focus();
                e.Cancel = true;
                return;
            }
            db2.SaveChanges();
            e.Cancel = false;
        }
        e.Cancel = false;
    }
}

真心希望得到帮助。一切顺利。请原谅我的英语。

最佳答案

Form1你有这段代码(请注意,为简洁起见,我用注释替换了一些代码):

public partial class Form1 : Form
{
    // code...
    private void Form1_Load(object sender, EventArgs e)
    {
        // code...
        modelBindingSource.DataSource = db2.Models.ToList();
        // code...
    }

    private void btnEdit_Click(object sender, EventArgs e)
    {
        // code...
        using (FormModel frm = new FormModel(modelBindingSource.Current as Model))
        {
            // code...
        }
    }
}

代码modelBindingSource.DataSource = db2.Models.ToList();正在设置 DataSource属性(property)Models . Models 中的所有内容从数据库加载;换句话说,db2 context 包含所有内容 Models .你刚从 db2 得到它所以它一定在那里。

代码using (FormModel frm = new FormModel(modelBindingSource.Current as Model))正在发送 ModelFormModel构造函数。

然后在FormModel ,你有这个代码:

public partial class FormModel : Form
{
    MyDBEntities db2;
    public FormModel(Model obj)
    {
        db2 = new MyDBEntities();
        // code...
        db2.Models.Attach(modelBindingSource.Current as Model);
    }

    // code...
}

在上面的代码中看到您附加了 Model到名为 db2 的新上下文但自 Model已附加到 db2Form1 ,异常被抛出,它清楚地告诉你:

An entity object cannot be referenced by multiple instances of IEntityChangeTracker

信息再清楚不过了。


修复

删除这行代码db2.Models.Attach(modelBindingSource.Current as Model);所以你没有附加它。不确定你为什么这样做。参见 this回答为什么以及何时需要调用 Attach .


清理

实际上从您发布的代码来看,objFormModel构造函数永远不能为空,所以这就是您在 FormModel 中需要的所有代码:

public partial class FormModel : Form
{
    public FormModel(Model obj)
    {
        InitializeComponent();

        modelBindingSource.DataSource = obj;
    }

    private void FormModel_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (DialogResult == DialogResult.OK)
        {
            if (string.IsNullOrEmpty(txtModelName.Text))
            {
                MessageBox.Show("Есть пустые поля", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Information);
                txtModelName.Focus();
                e.Cancel = true;
                return;
            }
        }
    }
}

然后你调用SaveChanges在你的Form1像这样:

using (FormModel frm = new FormModel(modelBindingSource.Current as Model))
{
    if (frm.ShowDialog() == DialogResult.OK)
    {
        modelBindingSource.DataSource = db2.Models.ToList(); // not sure if you need this
        db2.SaveChanges(); // <-- call save here since the dialog has been closed.
    }
}

附加说明

最后一点,FormModelForm1不是表单的好名称。好的表单名称应该表明表单的意图。例如,像 OrderEntryForm 这样的名称, OrderDetailForm etc. 都是好名字。

关于c# - 错误 "An entity object cannot be referenced by multiple instances of IEntityChangeTracker",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43959117/

相关文章:

sql-server - 在运行时连接 SQL 2008

c# - realm.xamarin 抛出错误 : The method 'Contains' is not supported. 与 'Any' 相同

c# - ASP.NET Core 6 WebAPI,无效模型未到达操作方法,而是立即返回 HTTP 400

c# - Mongodb 无法插入我的所有记录

c# - C# .NET 标签中的多种颜色

c# - C# 中的间隔容器

sql - 如何在 SQL Server 2012 上运行 1 GB .sql 文件?

c# - 引用已编译的 dll 时,Resharper 代码注释不起作用

c# - 无法在 Visual Studio 中添加对 Visual C# 控制台应用程序的引用

sql-server - 如何将 SSMS 连接到 docker 容器中的 Linux SqlServer?