What is the smartest way to find out if an entity is bound to dbContext or not?

when I try to snap an object to a context, I get an exception

An object with the same key already exists in the ObjectStateManager. ObjectStateManager cannot track multiple objects with the same key

This is the expected behavior.

But I would like to know how this ObjectStateManager knows? I would like to do this check myself before

+48
c # entity-framework-4 ef-code-first
May 17 '11 at 15:39
source share
5 answers

If you use the DbContext API (you mentioned ef-code-first), you can simply use:

context.YourEntities.Local.Any(e => e.Id == id); 

or more complex

 context.ChangeTracker.Entries<YourEntity>().Any(e => e.Entity.Id == id); 

In the case of the ObjectContext API, you can use:

 context.ObjectStateManager.GetObjectStateEntries(~EntityState.Detached) .Where(e => !e.IsRelationship) .Select(e => e.Entity) .OfType<YourEntity>() .Any(x => x.Id == id); 
+67
May 17 '11 at 21:19
source share

Here, the extension method is used to get the object out of context, without worrying that it is already attached:

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

Just call:

 UserProfile user = dbContext.UserProfiles.GetLocalOrAttach<UserProfile>(u => u.UserId == userId, () => new UserProfile { UserId = userId }); 
+10
Jun 17 '13 at 0:34
source share

verify

 entity.EntityState == System.Data.EntityState.Detached 

before attaching

+3
May 17 '11 at 15:45
source share

Note that if change tracking is disabled in your context, an ObjectStateManager or ChangeTracker may return that the object is not in the ObjectContext , even if it is actually already there. Therefore, if you try to attach such an object, it will throw an exception.

 context.Set<T>.Local.Any(e => e.Id == id); 

the event works if change tracking is disabled.

if you don’t know the type of the object, there is a different approach, either you define a method using reflection, or other methods like this int GetIdOf(object entity){...}

Or you define the interface used by your classes, e.g.

 public interface IMyEntity { int Id{get;set;} } 

and use it as follows:

 context.Set(e.GetType()).Local.Cast<IMyEntity>().Any(e => e.Id == id); 
+2
Apr 07 '14 at 13:40
source share

you can request dbContext using the "Any" extension method:

 bool alreadyInDB = dbContext.Entity.Where(a=>a.ID==myEntity.id).Any(); 
0
May 17 '11 at 21:16
source share



All Articles