附加类型为“X”的实体失败,因为相同类型的另一个实体已具有相同的主键值

时间:2016-12-29 08:53:34

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

ErrorMessage:

  

附加“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;
}

5 个答案:

答案 0 :(得分:11)

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

答案 1 :(得分:5)

您是否尝试将实体标记为已修改,然后将其附加到上下文?

像这样:

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;
}

答案 2 :(得分:0)

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

public bool Update(TEntity entity)
{

        context.Entry(entity).State = System.Data.EntityState.Modified;
        context.SaveChanges();
        return true;
}

答案 3 :(得分:0)

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

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;

答案 4 :(得分:0)

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