用相同的密钥对象已存在于objectstatemanager [英] Object with same key already exists in objectstatemanager

查看:146
本文介绍了用相同的密钥对象已存在于objectstatemanager的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

许多有关这个错误的问题,但我不能找出我的问题(也许我需要一些更多的解决这个问题的理论)。

Lots of questions about this error, and yet I cant figure out my problem (maybe i need some more of the theory around this).

我想趁自己的错误,什么我尝试做的是如此简单用相同的密钥在objectstatemanager已经存在的对象,我只是有一个编辑,查看客户端,其中有电话清单。由于SSON为用户点击保存按钮,我只是包装都使用JSON并将其发送给使用Ajax控制器。

I'm gettin the "Object with same key already exists in objectstatemanager" error and what im trying to do is so simple, I just have a Edit View for client, which has a list of Phones. As sson as the user hits the Save button, I just wrap everything with Json and send it to the controller with Ajax.

在控制器,即时通讯应该检查该名单上发送的手机,我应该更新,插入新闻和删除。

On the Controller, im supposed to check which phones on the list sent i should update, insert as news and delete.

因此​​,这里的code的重要组成部分(而抛出提到的exeception一):

So here's the important part of the code (and the one that throws the exeception mentioned):

            if (ModelState.IsValid)
            {
                foreach (var tel in propModel.Proprietario.Telefones)
                {
                    //Updates
                    TelefoneProprietario telToEdit = null;
                    if (tel.IDTelefoneProprietario.HasValue)
                        telToEdit = db.TelefonesProprietarios.Find(tel.IDTelefoneProprietario);
                    if (telToEdit != null)
                    {
                        db.Entry(tel).State = EntityState.Modified; << Exception HERE!!!
                    }
                    else
                    {
                        //Inserts
                        db.TelefonesProprietarios.Add(tel);
                    }
                }

                if (propModel.Proprietario.IDProprietario.HasValue)
                {
                    var prop = db.Proprietarios.Find(propModel.Proprietario.IDProprietario);
                    prop.LoadLists();
                    foreach (var telDel in prop.Telefones)
                    {
                        //Deletes
                        if (propModel.Proprietario.Telefones.Find(t => t.IDTelefoneProprietario == telDel.IDTelefoneProprietario) == null)
                        {
                            db.TelefonesProprietarios.Remove(telDel);
                        }
                    }
                }

                db.Entry(propModel.Proprietario).State = EntityState.Modified;
                db.SaveChanges();

                return Json(new { Success = 1, IDProprietario = propModel.Proprietario.IDProprietario, ex = "" });
            }

任何帮助或建议?

Any help or suggestions?

和使它更坏:我把行抛出异常时,只是为了测试code的休息,并在调用SaveChanges之前的最后一行,它抛出另一个异常:

And to make it even worst: I took the line throwing the exception out, just to test the rest of the code, and on the last line before the SaveChanges, it throws another exception:

The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects.

更新:

我设法解决这个问题的一部分重新写的另一种形式上面的程序,就像这样:

I manage to solve part of the problem re-writing the routine above in another form, like this:

                if (prop.IDProprietario.HasValue)
                {
                    //Separete updates/inserts from deletes
                    List<int?> dbTels = db.TelefonesProprietarios
                                    .Where(dt => dt.IDProprietario == prop.IDProprietario)
                                    .Select(dt => dt.IDTelefoneProprietario)
                                    .ToList();

                    List<int?> postedTels = prop.Telefones
                        .Select(pt => pt.IDTelefoneProprietario)
                        .ToList();

                    List<int?> deletedTels = dbTels
                        .Except(postedTels).ToList();

                    //Perform deletes
                    foreach (var delTelId in deletedTels)
                    {
                        if (delTelId.HasValue)
                        {
                            TelefoneProprietario delTel = db.TelefonesProprietarios
                                .Where(dt => dt.IDProprietario == prop.IDProprietario && dt.IDTelefoneProprietario == delTelId)
                                .Single();

                            db.Entry(delTel).State = EntityState.Deleted;
                        }
                    }

                    //Perform insert and updates
                    foreach (var tel in prop.Telefones)
                    {
                        if (tel.IDTelefoneProprietario.HasValue)
                        {
                            db.Entry(tel).State = EntityState.Modified;
                        }
                        else
                        {
                            db.Entry(tel).State = EntityState.Added;
                            tel.IDProprietario = (int)prop.IDProprietario;
                        }
                    }

                    db.Entry(prop).State = EntityState.Modified;
                }
                else 
                {
                    db.Proprietarios.Add(prop);
                }
                db.SaveChanges();

现在

唯一的问题留为删除的Proprietario实例(导致它有TelefoneProprietario的一个列表和该TelefoneProprietario具有基准回到那个ownes它的Proprietario此cenario导致不能,因为它们所限定的两个对象之间的关系连接到这里的SO广泛讨论......试图找出一个解决方案,因此,如果你能给我一些不同的东西ObjectContext的对象...)

Only problem left now is for deleting a Proprietario instance (cause it has a List of TelefoneProprietario and the TelefoneProprietario has a reference back to the Proprietario that ownes it. This cenario causes a "relationship between the two objects cannot be defined because they are attached to different ObjectContext objects" as widely discussed here in SO... Trying to figure out a solution, so if you can point me something...)

推荐答案

当你这样做: db.Entry(电话).STATE = EntityState.Modified;

电话对象只是一个对象模型,您传递的,对吧?

tel object is just a object model you pass in, right?

所以在这个时候EF上下文不保留有在相同的密钥与任何对象的跟踪电话的键在这种情况下的 IDTelefoneProprietario

So EF context at this time does not keep track of any object which has the same key with tel's key in this case IDTelefoneProprietario

因此​​,如果对象的状态设置为修改和的SaveChanges() EF将抛出错误。

Therefore if you set the object state to Modified then SaveChanges() EF will throw error.

做到这一点,而不是:

if (telToEdit != null)
{
    // Do apply all the changes from 'tel' to 'telToEdit' object here
    ...
    db.Entry(telToEdit).State = EntityState.Modified; // No Exception I hope :)
}

希望这是有道理的。

Hope it makes sense.

这篇关于用相同的密钥对象已存在于objectstatemanager的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆