【问题标题】:Error "An entity object cannot be referenced by multiple instances of IEntityChangeTracker"错误“IEntityChangeTracker 的多个实例无法引用实体对象”
【发布时间】:2017-05-13 23:58:27
【问题描述】:

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

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

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

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

我真的希望有所帮助。祝一切顺利。请原谅我的英语。

【问题讨论】:

  • 您将同一项目附加到多个上下文,这是不允许的。这就是你得到错误的方式。更多信息请参考this
  • 感谢您的回复。但我不知道如何在我的情况下解决这个问题。我查看了您的链接,但对我没有帮助。

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


【解决方案1】:

Form1 你有这个代码(注意,为了简洁,我已经用 cmets 替换了一些代码):

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 属性设置为ModelsModels 中的所有内容都是从数据库中加载的;换句话说,db2 上下文包含Models 中的所有内容。你刚刚从db2 得到它,所以它一定在那里。

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

然后在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已经附加到Form1中的db2,抛出异常,它清楚地告诉你这个:

一个实体对象不能被多个 IEntityChangeTracker 实例引用

信息再清楚不过了。


修复

删除这行代码db2.Models.Attach(modelBindingSource.Current as Model);,这样你就不会附加它了。不知道你为什么这样做。请参阅this 回答,了解为什么以及何时需要致电Attach


清理

实际上从您发布的代码来看,FormModel 构造函数中的obj 永远不能为空,所以这就是您在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;
            }
        }
    }
}

然后你像这样在Form1 中调用SaveChanges

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 不是表单的好名称。表格的好名字应该表明表格的意图。例如,OrderEntryFormOrderDetailForm 等名称都是好名称。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-03
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    相关资源
    最近更新 更多