0

关于这个错误有很多问题,但我无法弄清楚我的问题(也许我需要更多关于这个的理论)。

我遇到了“objectstatemanager 中已经存在具有相同键的对象”错误,而我尝试做的事情非常简单,我只有一个用于客户端的编辑视图,它有一个电话列表。当用户点击 Save 按钮时,我只需使用 Json 包装所有内容并使用 Ajax 将其发送到控制器。

在控制器上,我应该检查发送列表中的哪些电话我应该更新,作为新闻插入并删除。

所以这是代码的重要部分(以及引发上述异常的部分):

            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 = "" });
            }

有什么帮助或建议吗?

更糟糕的是:我把抛出异常的那一行去掉,只是为了测试代码的其余部分,在 SaveChanges 之前的最后一行,它抛出了另一个异常:

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

更新:

我设法解决了以另一种形式重写上述例程的部分问题,如下所示:

                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 有一个对拥有它的 Proprietario 的引用。这种情况导致“两个对象之间的关系无法定义,因为它们附加到不同的 ObjectContext 对象”,正如在 SO 中广泛讨论的那样......试图找出解决方案,所以如果你能指出我的东西......)

4

1 回答 1

1

当你这样做时:db.Entry(tel).State = EntityState.Modified;

tel对象只是您传入的对象模型,对吗?

因此,此时的 EF 上下文不会跟踪任何与tel 的密钥具有相同密钥的对象,在这种情况下是 IDTelefoneProprietario

因此,如果您将对象状态设置为已修改,则SaveChanges() EF 将引发错误。

改为这样做:

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

希望这是有道理的。

于 2012-11-11T17:14:12.723 回答