1. 首页>
  2. 技术文章>
  3. "Attach" 方法或者将实体的状态设置为 "Unchanged" 或 "Modified" 时如果图形中的任何实体具有冲突键值的解决方法

"Attach" 方法或者将实体的状态设置为 "Unchanged" 或 "Modified" 时如果图形中的任何实体具有冲突键值的解决方法

6/12/17 10:19:54 PM 浏览 2075 评论 1

EntityFramework

一、错误

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


网友讨论

1楼 11/15/17 10:46:18 AM
s