在更新或删除model的时候,出现错误:
ASP.NET MVC - Attaching an entity of type 'MODELNAME' failed because another entity of the same type already has the same primary key value
/// <summary>
/// 更新对象
/// </summary>
/// <param name="model">实体</param>
/// /// <returns></returns>
public virtual bool Update(T model)
{
this.DbContext.Entry<T>(model).State = EntityState.Detached;
this.DbContext.Set<T>().Attach(model);
this.DbContext.Entry<T>(model).State = EntityState.Modified;
return this.DbContext.SaveChanges() > 0;
}
/// <summary>
/// 删除对象
/// </summary>
/// <param name="model">实体</param>
public virtual bool Delete(T model)
{
this.DbContext.Set<T>().Remove(model);
return this.DbContext.SaveChanges() > 0;
}
原因:在Context中还保留有当前实体的副本所致,这里只要我们将实体副本从内存中完全移除,就可以了。
解决方式:
定义一个方法:用于监测Context中的Entity是否存在,如果存在,将其Detach,防止出现问题。
//用于监测Context中的Entity是否存在,如果存在,将其Detach,防止出现问题。
private Boolean RemoveHoldingEntityInContext(T entity)
{
var objContext = ((IObjectContextAdapter)_context).ObjectContext;
var objSet = objContext.CreateObjectSet<T>();
var entityKey = objContext.CreateEntityKey(objSet.EntitySet.Name, entity);
Object foundEntity;
var exists = objContext.TryGetObjectByKey(entityKey, out foundEntity);
if (exists)
{
objContext.Detach(foundEntity);
}
return (exists);
}
然后在update 或delete之前调用:
public T Remove(T entity)
{
try
{
RemoveHoldingEntityInContext(entity);
_context.DbSet<T>().Attach(entity);
return _context.DbSet<T>().Remove(entity);
}
catch (DbEntityValidationException dbex)
{
var msg = string.Empty;
foreach (var validationErrors in dbex.EntityValidationErrors)
foreach (var validateionError in validationErrors.ValidationErrors)
msg += string.Format("属性:{0} 错误:{1}", validateionError.PropertyName, validateionError.ErrorMessage);
var fail = new Exception(msg, dbex);
throw fail;
}
}
public T Update(T entity)
{
try
{
RemoveHoldingEntityInContext(entity);
var updated = _context.DbSet<T>().Attach(entity);
_context.DbContext.Entry(entity).State = EntityState.Modified;
return updated;
}
catch (DbEntityValidationException dbex)
{
var msg = string.Empty;
foreach (var validationErrors in dbex.EntityValidationErrors)
foreach (var validateionError in validationErrors.ValidationErrors)
msg += string.Format("属性:{0} 错误:{1}", validateionError.PropertyName, validateionError.ErrorMessage);
var fail = new Exception(msg, dbex);
throw fail;
}
}