EF5 How to get list of navigation properties for a domain object

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

Leave a Comment