使用反射过滤/删除EF5导航属性

时间:2014-11-20 09:39:45

标签: c# excel entity-framework asp.net-mvc-4 reflection

我有以下代码来获取传入的通用实体的所有属性。我认为这些属性可以很好地标记excel报告。但是当我使用它时,我得到了一堆"导航"属性。我想过滤它们,因为它们弄乱了报告。这是一些代码...

DataTable dataTable = new DataTable(typeof(TEntity).Name);

//Get properties / field names
PropertyInfo[] Props = typeof(TEntity).GetProperties(BindingFlags.Public | BindingFlags.Instance);

//Add props to datatable
foreach (PropertyInfo prop in Props)
    dataTable.Columns.Add(prop.Name);

因此代码继续将其他行添加到数据表中,然后我将其用于将数据发送到优秀的NPOI free excel导出工具。

理想情况下,BindingFlags属性是否允许我忽略

之类的内容
| !BindingFlags.Navigation

我也不需要其他2,因为无论是否有相同的细节,我都不需要。

如果没有BindingFlags属性,有没有办法可以扩展它。

如果没有,那么是否有其他标准方法可靠地检测它们,以便我可以将它们过滤掉。

我听说其中一些包含"导航"作为一个前缀,或几乎总是虚拟的,但我的似乎是虚拟的"几乎"部分让我担心。这就是我不想做的事情:

PropertyInfo[] Props = typeof(TEntity).GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => !p.GetGetMethod().IsVirtual && !p.GetGetMethod().IsFinal).ToArray();

然而我的没有"导航"我可以看到前缀,但如果他们这样做,我不相信这会给我正确的方法。

也许我对上述两个错了,或者我找不到合适的地方。

我还完成了生成一个" ViewModel"连接到repo以从模型获取数据并填充ViewModel的各种类型。然后将其发送到我的报告引擎。这似乎更灵活,因为我可以使用它类似于预览,如果我附加一个视图。这听起来像是正确的方式吗?

提前致谢...

1 个答案:

答案 0 :(得分:1)

正如弗朗西斯所说,你可以使用DbContext的元数据来获得给定实体类型的导航属性:

public static PropertyInfo[] GetNavigationProperties<TEntity>(DbContext context)
        where TEntity: class
    {
        var objContext = ((IObjectContextAdapter)context).ObjectContext;
        var elementType = objContext.CreateObjectSet<TEntity>().EntitySet.ElementType;
        return elementType.NavigationProperties.Select(prop => typeof(TEntity).GetProperty(prop.Name)).ToArray();
    }

然后你可以过滤你的属性,不包括导航属性,你的代码可能是这样的:

var dataTable = new DataTable(typeof(TEntity).Name);
var navProperties = GetNavigationProperties<TEntity>(ctx);

var props = typeof(TEntity).GetProperties(BindingFlags.Public | BindingFlags.Instance);

//Add props to datatable
foreach (var prop in props.Except(navProperties))
    dataTable.Columns.Add(prop.Name);