关闭

EF ObjectStateManager 中已存在具有同一键的对象。ObjectStateManager 无法跟踪具有相同键的多个对象

3801人阅读 评论(1) 收藏 举报
分类:

今天编码过程中遇到这个问题,在网上也查了一些所说的方式方法,但我不能使用,为什么这里面就不表述了

说重点吧。

我这个是这么理解的,出现这个问题应该是 ObjectContext 中被 attach 了几个相同的对象进去了。

所以在 context 中会出现至少两个主键一样的对象,所以这时EF被搞晕了。

我总结一下可能会解决的方法:

1. 

// 这句的意思是先把它从context 中分离出来, 这样就可以在上下文中操作了,是关键. 

this.context.Entry<sys_Company>(entry).State = System.Data.EntityState.Detached;
然后你可以继续 Attach/AttachTo

2. 你可以附加以前分离的对象、由 NoTracking 查询返回的对象或从对象上下文的外部获取的对象。
3. 第三种方法是对我的问题解决方法,我需要的是多张表的关联更新,一张主键表,多张外键表。
   其实很简单,就是先查,然后在更新~~~
   
	Company target = new Company();
	Mail.Model.Sys_Companys _company = target.DeleteCompanyModuleByCompanyID(C_ID);
        _company.C_Name = this.txt_CompanyName.Text.ToString();
        _company.C_Tel = this.txt_CompanyTel.Text.ToString();
        _company.C_Conatact = this.txt_CompanyConatact.Text.ToString();
        _company.C_Remark = this.txt_CompanyRemark.Text.ToString();
        Int32 iRow = 0;
        try
        {
             	UpdateCompanyModule(target, _company);
    		target.Update(_company, out iRow);// 这里你可以可以做你需要的更新了。
        }

	void UpdateCompanyModule(Company target, Sys_Companys _company)
    {
        //修改公司所有的模块
        string[] FieldChecked = FieldHiddenValue.Value.ToString().Split(';');
        string[] Checked = CheckboxHiddenValue.Value.ToString().Split(';');

        foreach (string fieldschecked in FieldChecked)
        {
            if (fieldschecked != string.Empty && fieldschecked != "")
            {
                Sys_CompanyModule sys_CM = target.CreateCompanyModule();
                string[] field = fieldschecked.Split('_');
                sys_CM.SM_ID = field[1].ToInt32();
                sys_CM.CM_Alias = field[2];
                sys_CM.C_ID = _company.C_ID;
                _company.Sys_CompanyModule.Add(sys_CM);
            }
        }

        //修改公司所有的子模块
        foreach (string checks in Checked)
        {
            if (checks != string.Empty && checks != "")
            {
                Sys_CompanysSubmodule sys_CSM = target.CreateCompanysSubmodule();
                string[] check = checks.Split('_');
                sys_CSM.SS_ID = check[1].ToInt32();
                sys_CSM.CS_Alias = check[2];
                sys_CSM.C_ID = _company.C_ID;
                _company.Sys_CompanysSubmodule.Add(sys_CSM);
            }
        }
............其它表就不列举了,我想也可以看明白了

先查,后更新,其实就是获取一个新对象, 然后在处理,这样它就有一个唯一的 entitykey, 就不会出现上面的问题了。


4. 第四方法,我觉得可以一试,而且也不错,就是通过entitykey,找到对象,然后Detach这个对象,随后再Attach我们新new 的对象
   
Sys_Companys co = new Sys_Companys { C_ID = id };
        object originalVal = null;
        System.Data.EntityKey key = _context.CreateEntityKey("Sys_Companys", co);
        if (_context.TryGetObjectByKey(key, out originalVal))
        {
            _context.Detach(originalVal);
        }

        co.C_Name = "";

        _context.Sys_Companys.Attach(co);

        co.C_Name = "我的名字";

        _context.SaveChanges();
        _context.Detach(co);
到这里就结束,祝君好运.
   



   
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:9391次
    • 积分:198
    • 等级:
    • 排名:千里之外
    • 原创:9篇
    • 转载:3篇
    • 译文:0篇
    • 评论:2条
    文章分类
    最新评论