Given the following code:
void MergeDbContext(DbContext aSourceDbContext, DbContext aDestinationDbContext)
{
var sourceEntities = aSourceDbContext.ChangeTracker.Entries().ToList();
foreach (DbEntityEntry entry in sourceEntities)
{
object entity = entry.Entity;
entry.State = EntityState.Detached;
// check if entity is all ready in aDestinationDbContext if not attach
bool isAttached = false;// TODO I don't know how to check if it is all ready attched.
if (!isAttached)
{
aDestinationDbContext.Set(entity.GetType()).Attach(entity);
}
}
}
How can I generically determine if an entity exists in the context.
This is an extension method that looks for an object in a context's state manager by the following steps:
- Get the type's key properties
- Get the object's key values
- Check if there is any entity in the context having the object's type and key values.
public static bool IsAttached<T>(this DbContext context, T entity)
where T : class
{
if (entity == null) return false;
var oc = ((IObjectContextAdapter)context).ObjectContext;
var type = ObjectContext.GetObjectType(entity.GetType());
// Get key PropertyInfos
var propertyInfos = oc.MetadataWorkspace
.GetItems(DataSpace.CSpace).OfType<EntityType>()
.Where(i => i.Name == type.Name)
.SelectMany(i => i.KeyProperties)
.Join(type.GetProperties(), ep => ep.Name, pi => pi.Name, (ep,pi) => pi);
// Get key values
var keyValues = propertyInfos.Select(pi => pi.GetValue(entity)).ToArray();
// States to look for
var states = System.Data.Entity.EntityState.Added|System.Data.Entity.EntityState.Modified
|System.Data.Entity.EntityState.Unchanged|System.Data.Entity.EntityState.Deleted;
// Check if there is an entity having these key values
return oc.ObjectStateManager.GetObjectStateEntries(states)
.Select(ose => ose.Entity).OfType<T>()
.Any(t => propertyInfos.Select(i => i.GetValue(t))
.SequenceEqual(keyValues));
}
Usage:
bool isAttached = dbContext.IsAttached(entity);