Tuesday, August 2, 2011

Entity Framework 4.1's NHibernate session.Evict(entity);

If you encountered this error..

System.InvalidOperationException: An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.

..you may want to evict your object. You can use this routine, granted that the program can access the old entity memory reference.

// (dbContext as IObjectContextAdapter).ObjectContext.Detach(entity);  // old EF of yore
dbContext.Entry(entity).State = System.Data.EntityState.Detached;


However, if you won't be able to reference the old entity, you can use the following helper to force-evict an entity based on its primary key:


Another approach for force-evicting object that already exists in the ObjectStateManager

private static void Evict(DbContext ctx, Type t, 
    string primaryKeyName, object id)
{            
    var cachedEnt =
        ctx.ChangeTracker.Entries().Where(x =>   
            ObjectContext.GetObjectType(x.Entity.GetType()) == t)
            .SingleOrDefault(x =>
        {
            Type entType = x.Entity.GetType();
            object value = entType.InvokeMember(primaryKeyName, 
                                System.Reflection.BindingFlags.GetProperty, null, 
                                x.Entity, new object[] { });

            return value.Equals(id);
        });

    if (cachedEnt != null)
        ctx.Entry(cachedEnt.Entity).State = EntityState.Detached;
}


Sample use:

Evict(yourDbContextHere, typeof(Product), "ProductId", 1);

No comments:

Post a Comment

Post a Comment