一、錯誤
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);
}