I wrote the following using EF6, but I believe it is all compatible with EF5. The general idea behind the code is to use the excellent classes in a System.Data.Metadata.Edm to get the navigation properties and use reflection on those property names to get the true properties of the object for updating.
I wanted to make my example as generic yet complete as possible. In the asker’s case, he’d just obviously replace “context” with “_uow.Context”.
public class MyClass<T> where T : class //T really needs to always be an entity,
//but I don't know a general parent type
//for that. You could leverage partial classes
//to define your own type.
{
public MyEntities context { get; set; }
public void UpdateValues(T originalEntity, T modifiedEntity)
{
//Set non-nav props
context.Entry(originalEntity).CurrentValues.SetValues(modifiedEntity);
//Set nav props
var navProps = GetNavigationProperties(originalEntity);
foreach (var navProp in navProps)
{
//Set originalEntity prop value to modifiedEntity value
navProp.SetValue(originalEntity, navProp.GetValue(modifiedEntity));
}
}
public List<System.Reflection.PropertyInfo> GetNavigationProperties(T entity)
{
List<System.Reflection.PropertyInfo> properties = new List<System.Reflection.PropertyInfo>();
//Get the entity type
Type entityType = entity.GetType();
//Get the System.Data.Entity.Core.Metadata.Edm.EntityType
//associated with the entity.
var entitySetElementType = ((System.Data.Entity.Infrastructure.IObjectContextAdapter)context).ObjectContext.CreateObjectSet<T>().EntitySet.ElementType;
//Iterate each
//System.Data.Entity.Core.Metadata.Edm.NavigationProperty
//in EntityType.NavigationProperties, get the actual property
//using the entityType name, and add it to the return set.
foreach (var navigationProperty in entitySetElementType.NavigationProperties)
{
properties.Add(entityType.GetProperty(navigationProperty.Name));
}
return properties;
}
}