【问题标题】:Attaching an entity of type 'X' failed because another entity of the same type already has the same primary key value附加类型为“X”的实体失败,因为同一类型的另一个实体已经具有相同的主键值
【发布时间】:2017-05-13 13:40:29
【问题描述】:

错误消息:

附加类型为“FaridCRMData.Models.Customer”的实体失败 因为另一个相同类型的实体已经有相同的主 核心价值。 使用 Attach() 方法或设置 如果图中的任何实体具有冲突的 > 键值,则将实体设置为“未更改”或“已修改”。这可能是因为有些实体是新的,尚未收到 数据库生成的键值。在这种情况下,使用“添加”方法或“添加” 实体状态来跟踪图,然后将非新实体的状态设置为 “未更改”或“已修改”(视情况而定)。

我的代码:

public class FactorController : Controller
{
    public JsonResult SaveFactor(Factor factor,int id)
    {
        if (id > 0)
        {
            bool result = new FactorService.BaseService.Update(factor);
            return new JsonResult() { Data = result };
        }

    }
}

FactorService.BaseService.cs:

public bool Update(TEntity entity)
{
    var entry = context.Entry(entity);
    if (entry.State == EntityState.Detached || entry.State == EntityState.Modified)
    {

        context.Set<TEntity>().Attach(entity);// Error Is Here
        entry.State = EntityState.Modified;
        context.SaveChanges();
    }
    return true;
}

【问题讨论】:

  • 问题是对象已经存在于具有该 ID 的上下文中。如果它已经存在,则无需附加

标签: c# asp.net-mvc entity-framework


【解决方案1】:

我相信你可能在更新之前调用了 Select,默认情况下,DBContext 会在记录被选中(选择)时缓存记录,在获取记录时在 select 调用中使用“AsNoTracking()”。

【讨论】:

  • 这是最合适的答案。
  • 这是我一直在寻找的答案!这是我的例子,以防它帮助其他人弄清楚它应该去哪里。例如:var recordToUpdate = db.Reservations.AsNoTracking().Single(x =&gt; x.ID == reservation.ID); 接下来的几行是我不想在编辑页面上更新的记录中的值,然后是 db.Entry(reservation).State = EntityState.Modified;db.SaveChanges();
【解决方案2】:

您是否尝试在将实体附加到上下文之前将其标记为已修改?

像这样:

public bool Update(TEntity entity)
{
    var entry = context.Entry(entity);
    if (entry.State == EntityState.Detached || entry.State == EntityState.Modified)
    {
        entry.State = EntityState.Modified; //do it here

        context.Set<TEntity>().Attach(entity); //attach

        context.SaveChanges(); //save it
    }
    return true;
}

【讨论】:

  • 快乐帮助你!!..EF的奥秘;-)
  • 好吧,如果第一个语句 (entry.State = EntityState.Modified) 成功,则附加条目。 EF 如何设置未附加条目的状态?为什么|| entry.State == EntityState.Modified?将Modified 实体设置为Modified 有什么意义?换句话说,将条目的状态设置为Modified 就足够了。检查条目是否不是Deleted 更有用。
  • 出于某种原因,我需要将State=EntityState.Modified 移动到函数的开头,然后才实际修改任何内容。如果它在 SaveChanges 附近结束,它每次都会崩溃。
【解决方案3】:

如果您在更新操作之间选择一些数据(因为我遇到了问题)。 不要使用 .ToList().Find() .... 而不是使用 as IQueryable ,然后使用 .AsNoTracking().....问题解决了。

【讨论】:

    【解决方案4】:

    您需要先分离本地版本,然后进行更新过程

    var localEntity = dbContext.Set<theModel>()
        .Local
        .FirstOrDefault(f => f.Id == theModel.Id);
    if (localEntity != null)
    {
        dbContext.Entry(localEntity).State = EntityState.Detached;
    }
    dbContext.Entry(appModel).State = EntityState.Modified;
    

    【讨论】:

      【解决方案5】:

      为您尝试更新和SaveChanges()的实体尝试简单的更改状态

      public bool Update(TEntity entity)
      {
      
              context.Entry(entity).State = System.Data.EntityState.Modified;
              context.SaveChanges();
              return true;
      }
      

      【讨论】:

        猜你喜欢
        • 2015-01-08
        • 2014-07-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-05
        • 2023-03-23
        相关资源
        最近更新 更多