存储库模式在更新记录时给出异常

时间:2014-09-03 05:25:43

标签: asp.net-mvc entity-framework repository-pattern data-access-layer

在我的MVC应用程序中,我一直在使用DAL的Repository模式。

现在,当我选择一个实体记录并更新实体字段值并执行更新操作然后低于错误。

  

附加“DAL.User”类型的实体失败,因为另一个实体   相同类型的已经具有相同的主键值。这个可以   使用“附加”方法或设置状态时发生   如果图中的任何实体具有,则实体为“未更改”或“已修改”   冲突的关键值。这可能是因为一些实体是新的和   尚未收到数据库生成的键值。在这种情况下使用   “添加”方法或“已添加”实体状态可跟踪图表和   然后将非新实体的状态设置为“未更改”或“已修改”为   适当的。“} System.Exception

以下是存储库内容:

public void Update(TEntity entity)
{
    if (_context.Entry(entity).State != EntityState.Modified)
    {
         _dbSet.Attach(entity);
        _context.Entry(entity).State = EntityState.Modified;
    }
}

请致电如下:       在Bussines图层库中:           经理班:

    private readonly IUnitOfWork _unitOfWork;
    private IRepository <User , int> UserRepository
    {
        get
        {
            return _unitOfWork.GetRepository<AccountUser, int>();
        }
    }
    public void UpdateUserEntity(UserDTO u)
    {
        try
        {

            User model = new User ();
            UserRepository.Update(Mapper.Map(u, model));
            _unitOfWork.SaveChanges();
        }
        catch (Exception ex)
        {
            throw;
        }
    }

请指导我如何解决上述错误。

2 个答案:

答案 0 :(得分:3)

例外情况说,有另一个实体具有相同的附加键,但引用不同。

  • 异常可能是由之前的附加实体引起的。

    db.Set<Entity>().Attach(new Entity { Id = 123 });
    db.Set<Entity>().Attach(new Entity { Id = 123 }); // different reference but same key
    
  • 或者也可能是由自动附加的跟踪实体引起的。

    db.Set<Entity>().FirstOrDefault(e => e.Id == 123); // automatically attached
    db.Set<Entity>().Attach(new Entity { Id = 123 }); // different reference but same key
    

第二个原因可以通过在检索项目时提及AsNoTracking来解决。

db.Set<Entity>().AsNoTracking().FirstOrDefault(e => e.Id == 123);

或者为了安全起见,您可以使用此扩展程序始终分离任何附加的实体。

public static class DbSetExtension
{
    public static void SafeAttach<T>(
        this DbContext context, 
        T entity, 
        Func<T, object> keyFn) where T : class
    {
        var existing = context.Set<T>().Local
            .FirstOrDefault(x => Equals(keyFn(x), keyFn(entity)));
        if (existing != null)
            context.Entry(existing).State = EntityState.Detached;

        context.Set<T>().Attach(entity);
    }
}

使用。

db.SafeAttach(entity, e => e.Id);

答案 1 :(得分:0)

由于这个原因, &#34; TEntity实体作为新对象而不是已存在的对象&#34;。 Means,Entity框架将每个新对象视为新条目。(尽管使用相同的现有旧数据,PK&amp; all)。

解决方案是,

  

首先从数据库中检索对象

     

将更改分配给同一对象(最好不更改主键)

     

然后将状态改为Modified,Update,SaveChange()