如何知道存储在 DbEntityEntry 中的 属性 是否是 属性`?

How to know whether a property stored in DbEntityEntry is a property`?

在 Entity Framework 6 中 DbEntityEntry 可以通过调用 Property 检索某些信息。 但是,当 属性 不是 属性 而是集合或引用时,此操作失败并显示 ArgumentException。一定要用到其他功能。

我怎么知道要调用哪个函数?也就是说,我怎么知道 属性 是什么类型(简单 属性、复杂 属性、引用、集合)?

对于 DbEntityEntry,请参阅 https://msdn.microsoft.com/en-us/library/system.data.entity.infrastructure.dbentityentry%28v=vs.113%29.aspx

我在 Visual Studio 2013 年使用 Entity Framework 6.1.3。

我找到了如何获取导航 属性 是否为 collection 类型。 为此,我们需要获取 属性.

BuiltInTypeKind

我正在使用此代码获取实体的所有导航属性:

var entitySetElementType = ((IObjectContextAdapter)context).ObjectContext.CreateObjectSet<TEntity>().EntitySet.ElementType;
var navProperties = entitySetElementType.NavigationProperties;

然后,我们可以知道导航属性是否是collection:

foreach (var navigationProperty in entiySetElementType.NavigationProperties)
{
      var builtInType = navigationProperty.TypeUsage.EdmType.BuiltInTypeKind;
      var isCollection = builtInType == System.Data.Metadata.Edm.BuiltInTypeKind.CollectionKind
                      || builtInType == System.Data.Metadata.Edm.BuiltInTypeKind.CollectionType;
}

更新

由于 EF 已移至单独的程序集和命名空间,因此上述代码中的 System.Data.Metadata.Edm.BuiltInTypeKind.CollectionKind 应更改为 System.Data.Entity.Core.Metadata.Edm.BuiltInTypeKind.CollectionKind

其中一个步骤是挖掘那些动态代理。我这样做:

    if ( targetType.BaseType != null
        && targetType.Namespace == "System.Data.Entity.DynamicProxies" )
    {
        targetType = targetType.BaseType;
    }

不是很干净,但也够用了。

更新

根据jjj的回答,我想到了以下方法:

        private bool IsSimpleProperty( string propertyName, DbEntityEntry entry )
        {
            DbMemberEntry memberEntry = entry.Member( propertyName );

            return memberEntry is DbPropertyEntry;
        }

通过改变 is 表达式,您可以检查所有类型。

DbEntityEntry.Member(string) returns 一个 DbMemberEntry,你可以用 (memberEntry is DbPropertyEntry).

查看