Get Navigation Properties of given EntityType
You can filter GetProperties
results to get only these which implement ICollection
or IEnumerable
. However, you should remember that string
implements IEnumerable
, so you have to add additional check not to return string
properties.
return entityType.GetProperties()
.Where(p => typeof(IEnumerable).IsAssignableFrom(p.PropertyType) && p.PropertyType != string)
.Select(p => p.Name)
.ToArray();
Update
You can change you Where
predicate to compare namespaces as well. It returns also 1:1 navigation properties:
private static string[] GetNaviProps(Type entityType)//eg typeof(Employee)
{
return entityType.GetProperties()
.Where(p => (typeof(IEnumerable).IsAssignableFrom(p.PropertyType) && p.PropertyType != typeof(string)) || p.PropertyType.Namespace == entityType.Namespace)
.Select(p => p.Name)
.ToArray();
}
Based on this answer
private static List<PropertyInfo> GetNavigationProperties(Type t)
{
var navigationProperties = new List<PropertyInfo>();
if (t.BaseType != null && t.Namespace == "System.Data.Entity.DynamicProxies") {
t = t.BaseType;
}
string fkName = t.Name + "Id";
var allProps = new List<PropertyInfo>();
foreach (PropertyInfo p in t.GetProperties()) {
if (p.PropertyType.IsGenericType) {
dynamic GenericTypeDefinition = p.PropertyType.GetGenericTypeDefinition();
if (GenericTypeDefinition == typeof(ObservableCollection<>) || GenericTypeDefinition == typeof(ICollection<>) || GenericTypeDefinition == typeof(IEnumerable<>)) {
allProps.Add(p);
}
}
}
foreach (PropertyInfo prop in allProps) {
// This checks if the other type has a FK Property of this Type.
var type = prop.PropertyType.GetGenericArguments().First();
bool HasOneProperty = type.GetProperties().Any(x => x.Name.Equals(fkName, StringComparison.OrdinalIgnoreCase));
if (HasOneProperty) {
navigationProperties.Add(prop);
}
}
return navigationProperties;
}
I know I'm a little late to the party, but you can use the Entity Framework way to retrieve the navigation properties instead of using reflection:
MetadataWorkspace workspace = ((IObjectContextAdapter)this.Context).ObjectContext.MetadataWorkspace;
ObjectItemCollection itemCollection = (ObjectItemCollection)(workspace.GetItemCollection(DataSpace.OSpace));
EntityType entityType = itemCollection.OfType<EntityType>().Single(e => itemCollection.GetClrType(e) == typeof(TEntity));
where this.Context
is an instance of the DbContext
class. After that you can access the EntityType's NavigationProperties property.