我正在尝试获取所有实体(模型),然后只有ICollection
类型的导航属性,但它似乎不起作用,这是我到目前为止所尝试的,
foreach (var propertyInfo in new CompanyDBContext().GetType()
.GetProperties(
BindingFlags.Public
| BindingFlags.Instance))
{
Console.WriteLine(propertyInfo.Name);
//var entity = DbSet<propertyInfo.Name>
}
我能够使用上面的代码获取我拥有的所有模型,但是如何获得下一个ICollection
类型的所有导航属性?
答案 0 :(得分:1)
您必须先从DbContext
获取所有实体的类型。 DbSet<>
中定义的DbContext
类型的任何属性实际上都包含一个实体。你需要抓住它。
private static readonly Type DbSetType = typeof(DbSet<>);
private static IEnumerable<Type> GetAllEntityTypes(Type contextType)
{
return contextType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Select(p => p.PropertyType)
.Where(t => t.IsGenericType && t.GetGenericTypeDefinition() == DbSetType)
.Select(t => t.GetGenericArguments()[0]);
}
要从Entity
类型获取导航属性,这里有一个辅助方法,它是https://stackoverflow.com/a/27124251/2509344
private static readonly MethodInfo CreateObjectSetMethodInfo = typeof(ObjectContext).GetMethod("CreateObjectSet", new Type[0]);
private static readonly Type CollectionType = typeof(ICollection<>);
private static IEnumerable<PropertyInfo> GetNavigationProperties(DbContext context, Type entityType)
{
var objectContext = ((IObjectContextAdapter)context).ObjectContext;
var createObjectSetMethod = CreateObjectSetMethodInfo.MakeGenericMethod(entityType);
var entity = createObjectSetMethod.Invoke(objectContext, new object[0]);
var entitySet = (EntitySet)entity.GetType().GetProperty("EntitySet").GetValue(entity);
var elementType = entitySet.ElementType;
return elementType.NavigationProperties.Select(p => entityType.GetProperty(p.Name))
// Filter Properties that are of type ICollection
.Where(p => p.PropertyType.IsGenericType && p.PropertyType.GetGenericTypeDefinition() == CollectionType);
}
最后获取DbContext
中定义的实体的所有导航属性:
var context = new CompanyDBContext();
var entities = GetAllEntityTypes(context.GetType());
foreach (var entity in entities)
{
var navigationProperties = GetNavigationProperties(context, entity).ToList();
}