一、错误
EF中附加类型“**”的实体失败,因为相同类型的其他实体已具有相同的主键值。在使用 "Attach" 方法或者将实体的状态设置为 "Unchanged" 或 "Modified" 时如果图形中的任何实体具有冲突键值,则可能会发生上述行为。这可能是因为某些实体是新的并且尚未接收数据库生成的键值。在此情况下,使用 "Add" 方法或者 "Added" 实体状态跟踪该图形,然后将非新实体的状态相应设置为 "Unchanged" 或 "Modified"。
二、错误原因
1.直接使用了查询出来的实体,然后附加,可能出现此问题,
解决办法:在查询语句中添加.AsNoTracking()(即查询结果上下文不进行跟踪);如 DbContext.Set<T>().AsNoTracking();
2.在使用 DbContext.Entry<T>(t).State = EntityState.Modified; 使用 EntityState.Modified后会自动跟踪实体,如果再次附加也会出现此问题。
解决办法:
直接查找上下文中是否存在此实体,如果存在则移除,然后再进行操作,此方法在大部分情况下有效。
/// <summary> /// 如果上下文中存在对象则移除 /// </summary> /// <param name="entity"></param> /// <returns></returns> public bool Exists(T entity) { ObjectContext _ObjContext = ((IObjectContextAdapter) DbContext).ObjectContext; ObjectSet < T > _ObjSet = _ObjContext.CreateObjectSet < T > (); var entityKey = _ObjContext.CreateEntityKey(_ObjSet.EntitySet.Name, entity); Object foundEntity; var exists = _ObjContext.TryGetObjectByKey(entityKey, out foundEntity); // TryGetObjectByKey attaches a found entity // Detach it here to prevent side-effects if (exists) { _ObjContext.Detach(foundEntity); } return (exists); }