找出实体是否附加到dbContext的最合理方法是什么?

max*_*ego 56 c# entity-framework-4 ef-code-first

当我尝试将实体附加到上下文时,我得到一个例外

ObjectStateManager中已存在具有相同键的对象.ObjectStateManager无法使用相同的键跟踪多个对象

这是预期的行为.

但我想知道ObjectStateManager是如何知道的?我之前想自己做这个检查

Lad*_*nka 77

如果您使用的是DbContext API(您首先提到了ef-code),您可以使用:

context.YourEntities.Local.Any(e => e.Id == id);
Run Code Online (Sandbox Code Playgroud)

或者更复杂

context.ChangeTracker.Entries<YourEntity>().Any(e => e.Entity.Id == id);
Run Code Online (Sandbox Code Playgroud)

对于ObjectContext API,您可以使用:

context.ObjectStateManager.GetObjectStateEntries(~EntityState.Detached)
                          .Where(e => !e.IsRelationship)
                          .Select(e => e.Entity)
                          .OfType<YourEntity>()
                          .Any(x => x.Id == id);
Run Code Online (Sandbox Code Playgroud)

  • 但是你可以在你的实体中重写equals并简单地调用`Any(e => e.Equals(yourEntity)) (2认同)

Dav*_*ret 13

这是一个从上下文中获取对象的扩展方法,而不必担心它是否已经附加:

public static T GetLocalOrAttach<T>(this DbSet<T> collection, Func<T, bool> searchLocalQuery, Func<T> getAttachItem) where T : class
{
    T localEntity = collection.Local.FirstOrDefault(searchLocalQuery);

    if (localEntity == null)
    {
        localEntity = getAttachItem();
        collection.Attach(localEntity);
    }

    return localEntity;
}
Run Code Online (Sandbox Code Playgroud)

只需致电:

UserProfile user = dbContext.UserProfiles.GetLocalOrAttach<UserProfile>(u => u.UserId == userId, () => new UserProfile { UserId = userId });
Run Code Online (Sandbox Code Playgroud)


Kai*_*ido 5

校验

entity.EntityState == System.Data.EntityState.Detached
Run Code Online (Sandbox Code Playgroud)

附加之前

  • 我要添加的实体已分离,但是可能已经有具有相同ID的实体加载到dbcontext中。 (11认同)