实体框架:具有相同键的对象已存在于objectstatemanager [英] Entity Framework: An object with the same key already exists in the objectstatemanager

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

问题描述

我看到,这个问题已经被问了很多,但我还没有发现任何东西,解决了我遇到的问题。

显然,我使用的是实体框架来执行更新至创纪录的。一旦更新完成,但是,每当我试图挽救我收到以下错误信息:

 具有相同键的对象已存在于objectstatemanager
 

起初我传递从包含的副本视图的集合对象中的邮编codeTerritory 模型对象 zipToUpdate 。我拉这个目标了​​,只是发在相关领域,而不是改变了code。不过,我仍然得到同样的错误。

什么也奇怪的是我第一次运行这个code,它工作正常。之后,我得到错误的任何尝试。

控制器

下面是从方法调用编辑功能的code

 公共静态字符串DescriptionOnly(邮编codeINDEX updateZip)
{
    如果(!string.IsNullOrWhiteSpace(updateZip.newEffectiveDate)||!string.IsNullOrWhiteSpace(updateZip.newEndDate))
    {
        回报无论是有效的还是结束日期可能是present如果只更新区域code;;
    }

    _updated = 0;

    的foreach(在updateZip.displayForPaging.Where VAR拉链code(X => x.Update))
    {
        ProcessAllChanges(ZIP code,updateZip.newTerritory,updateZip.newState code,updateZip.newDescription,updateZip.newChannel code);
    }

    _msg + = _updated +结果更新;;

    返回_msg;
}
 

下面是实际执行更新的方法。

 私有静态无效ProcessAllChanges(邮编codeTerritory zipToUpdate,串newTerritory,串newState code,串newDescription,串newChannel code)
{
    尝试
    {
        如果(string.IsNullOrWhiteSpace(newTerritory)!)zipToUpdate.IndDistrnId = newTerritory;
        如果(!string.IsNullOrWhiteSpace(newState code))zipToUpdate.State code = newState code;
        如果(string.IsNullOrWhiteSpace(newDescription)!)zipToUpdate.DrmTerrDesc = newDescription;
        如果zipToUpdate.Channel code = newChannel code(string.IsNullOrWhiteSpace(newChannel code)!);
        如果(zipToUpdate.EndDate == DateTime.MinValue)zipToUpdate.EndDate = DateTime.MaxValue;

        _db.Entry(zipToUpdate).State = EntityState.Modified;
        _db.SaveChanges();
        _updated ++;
    }
    赶上(DbEntityValidationException dbEx)
    {
        _msg + =更新过程中出错;;
        EventLog.WriteEntry(莫奈,在ProcessAllChanges错误:+ zipToUpdate.ToString()+| EX |+ dbEx.Message);
    }
    赶上(例外前)
    {
        _msg + =更新过程中出错;;
        EventLog.WriteEntry(莫奈,在ProcessAllChanges错误:+ zipToUpdate.ToString()+|留言|+ ex.Message);
    }
}
 

修改

邮编codeINDEX 对象包含邮编codeTerritory 模型对象的列表。这些未从LINQ查询拉升,而是简单地传递回从视图控​​制器。下面是控制方法的启动过程中的签名:

  [HttpPost]
公众的ActionResult更新(邮编codeINDEX updateZip,弦钮)
 

解决方案

这是由于inproper处理数据库方面的,因为你永远不会处理上下文对象本身,你会遇到这类问题的。

我会建议包裹code在using语句。

 使用(VAR上下文=新MyContext())
{
   //这里做我节省code ...
}
 

这将确保妥善处置的背景下!

I see that this question has been asked a lot, however I haven't found anything yet that solves the problem I'm having.

Obviously i'm using the Entity Framework to perform an update to a record. Once the updates are complete, however, whenever I try to save I get the following error message:

An object with the same key already exists in the objectstatemanager

At first I was passing in a collection object from the view that contained a copy of the the ZipCodeTerritory model object zipToUpdate. I changed the code by pulling this object out and just sending in the relevant fields instead. However, I'm still getting the same error.

What's also weird is the first time I run this code, it works fine. Any attempt after that I get the error.

Controller

Here is the code from the method calling the edit function

public static string DescriptionOnly(ZipCodeIndex updateZip)
{
    if (!string.IsNullOrWhiteSpace(updateZip.newEffectiveDate) || !string.IsNullOrWhiteSpace(updateZip.newEndDate))
    {
        return "Neither effective or end date can be present if updating Territory Code only; ";
    }

    _updated = 0;

    foreach (var zipCode in updateZip.displayForPaging.Where(x => x.Update))
    {
        ProcessAllChanges(zipCode, updateZip.newTerritory, updateZip.newStateCode, updateZip.newDescription, updateZip.newChannelCode);
    }

    _msg += _updated + " record(s) updated; ";

    return _msg;
}

And here is the method that actually does the updating.

private static void ProcessAllChanges(ZipCodeTerritory zipToUpdate, string newTerritory, string newStateCode, string newDescription, string newChannelCode)
{
    try
    {
        if (!string.IsNullOrWhiteSpace(newTerritory)) zipToUpdate.IndDistrnId = newTerritory;
        if (!string.IsNullOrWhiteSpace(newStateCode)) zipToUpdate.StateCode = newStateCode;
        if (!string.IsNullOrWhiteSpace(newDescription)) zipToUpdate.DrmTerrDesc = newDescription;
        if (!string.IsNullOrWhiteSpace(newChannelCode)) zipToUpdate.ChannelCode = newChannelCode;
        if (zipToUpdate.EndDate == DateTime.MinValue) zipToUpdate.EndDate = DateTime.MaxValue;

        _db.Entry(zipToUpdate).State = EntityState.Modified;
        _db.SaveChanges();
        _updated++;
    }
    catch (DbEntityValidationException dbEx)
    {
        _msg += "Error during update; ";
        EventLog.WriteEntry("Monet", "Error during ProcessAllChanges: " + zipToUpdate.ToString() + " |EX| " + dbEx.Message);
    }
    catch (Exception ex)
    {
        _msg += "Error during update; ";
        EventLog.WriteEntry("Monet", "Error during ProcessAllChanges: " + zipToUpdate.ToString() + " |MESSAGE| " + ex.Message);
    }
}

EDIT

The ZipCodeIndex object contains a list of ZipCodeTerritory model objects. These aren't being pulled from a linq query, but instead simply passed back to the controller from the view. Here is the signature of the controller method that starts the process:

[HttpPost]
public ActionResult Update(ZipCodeIndex updateZip, string button)

解决方案

This is due to inproper disposal of the database context, as you are never disposing of the context object itself you will run into these kinds of problems.

I would suggest wrapping the code in a using statement..

using (var context = new MyContext())
{
   // Do my save code here...
}

That will ensure proper disposal of the context!

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

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