如何从Entity Framework的模型元数据中获取树结构

时间:2015-12-08 14:22:51

标签: c# entity-framework

我正在开发一个动态报表生成器,它允许最终用户使用Entity Framework模型基本上创建自己的SELECT语句。让我首先描述一下我想要达到的目标:

  1. 用户选择实体(例如'学生'),
  2. 他获得了一个列表,其中包含实体属性(' FirstName',' LastName'等及其类型)和相关实体('注册')。主要和外键属性不包括在内,
  3. 在此列表中,相关实体的行为类似于目录,用户可以单击它们以树形结构显示其属性和相关实体,
  4. 用户可以选择任何属性(稍后需要创建动态SELECT语句)。
  5. 我在考虑使用反射这样做,这似乎是一种相对简单的方法,但是存在一些限制(比如确定属性是否是外键)。我知道还有MetadataWorkspace类,但它对我来说非常混乱,以前从未使用过它。我还需要提一下,我知道潜在的参考循环,因此相关实体会有深度限制。我怎样才能创建这样的实体关系树?

    其他信息

    我忘了提到,我正在做的这个项目是一个可重用的库,所以它应该适用于任何dbContext,最好(如果可能的话)而不需要修改模型或添加属性。

1 个答案:

答案 0 :(得分:0)

您的开发指南:

  • 以下方法可以提取模型的所有类属性:

    public static IEnumerable<PropertyInfo> ExtractTypeProperties(Type type)
    {
        return type.GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public |
                               BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);
    }
    
  • 导航属性通常为virtual。你可以使用这样的东西来获得这些属性:

    foreach (var property in typeof(MyModel).GetProperties().Where(p => p.GetGetMethod().IsVirtual)) { ... }
    
  • 模型主键的名称通常为IdTheModelId或用[Key]装饰;

  • 模型外键通常具有相同名称的关联导航属性,Id后缀除外,或者用[ForeignKey]修饰。请注意,导航属性也可以使用此属性进行修饰,因此我认为您必须进行复核以满足所有约定;
  • 避免从EF本身反映所选对象,因为EF会用动态代理替换导航属性。更喜欢反映班级类型。