General way to check for entity in Entity framework?

What is the best way to check if an object exists in the Entity Framework?

I am looking for a general way to validate an object in DbSet . Something like this that doesn't work:

 private DbContext DbContext { get; set; } private DbSet<T> DbSet { get; set; } public Boolean Exists(T entity) { return ((from item in this.DbSet where item == entity select item).Count() > 0); } 

The where item == entity works in LINQ to SQL, but apparently not with LINQ to Entities. Since entities can have different keys, I cannot inherit them from a common paragraph with a known key for comparison.

I could do this, but I'm worried about the performance of catching exceptions as a validation process. This does not work as long as the object is not detached, the OriginalValues property can't:

 public Boolean Exists(T entity) { try { var current = this.DbContext.Entry(entity).OriginalValues; // Won't reach this line if the entity isn't in the database yet return true; } catch (Exception ex) { return false; } } 
+52
May 16 '11 at 14:15
source share
2 answers

Do you want a general way to check if an object has been loaded in a context or in a general way to query a database if an entity exists?

In the first case, use:

 public bool Exists<T>(T entity) { return this.Set<T>().Local.Any(e => e == entity); } 

In the latter case, use (it will also check the loaded objects):

 public bool Exists<T>(params object[] keys) { return (this.Set<T>().Find(keys) != null); } 

Edit:

The EF code should not first access this information, but you can get the name of the entity. I think something like this should work:

 var objContext = ((IObjectContextAdapter)dbContext).ObjectContext; var objSet = objContext.CreateObjectSet<T>(); var keyNames = objSet.EntitySet.ElementType.KeyMembers.Select(m => m.Name); 

But all this does not make sense. You want to use a general approach, but your entities do not provide the necessary information to provide a general approach. Now you say that you donโ€™t even know the key meanings. Using this โ€œgeneralโ€ approach will require reflection and manual construction of the expression tree.

+76
May 16 '11 at 14:59
source share

Thanks @Ladislav for taking me in the right direction. Here is the code for the generic Exists() method.

I would like to note that this does not require reflection and seems to work quite well. The only thing I donโ€™t worry about is that TryGetObjectByKey() has the side effect of attaching the found entity. Since I do not want Exists() have this unintended result, I had to separate the object if it was found.

 public Boolean Exists(T entity) { var objContext = ((IObjectContextAdapter)this.DbContext).ObjectContext; var 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); } 
+20
May 18 '11 at 21:30
source share



All Articles