加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 错误“IEntityChangeTracker的多个实例无法引用实体对象”

发布时间:2020-12-15 22:44:32 所属栏目:百科 来源:网络整理
导读:朋友. 我真的需要你的帮助.我会很感激. 所以我在MS SQL Server中有实体“Model”c字段“ID_model”和“name”. 我想,在Form1上单击“编辑”后,还有另一个表单(FormModel),您可以在其中更改数据并将更改写入数据库. 问题是在按下“编辑”后出现“附加信息:IE
朋友.
我真的需要你的帮助.我会很感激.

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

使用(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,因此抛出异常,它清楚地告诉您:

An entity object cannot be referenced by multiple instances of IEntityChangeTracker

消息不能比那更清楚.

固定

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

清理

实际上,从您发布的代码中,FormModel构造函数中的obj永远不能为null,因此这是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("Есть пустые поля","Ошибка",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.
    }
}

补充说明

最后一点,FormModel和Form1不是表单的好名字.表格的好名称应该表明表格的意图.例如,OrderEntryForm,OrderDetailForm等名称是好名字.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读