使用GetProperties时如何区分导航属性和常规属性?

She*_*115 5 c# reflection entity-framework

有没有办法在Entity-Framework类(数据库优先)上区分常规集合属性和导航属性?

我目前正在检查对象is ICollectionIsVirtual但是我认为这可能会在有人声明为虚拟集合的常规属性上触发。

问题:还有其他方法可以将导航属性与其他属性区分开吗?

上下文:我正在使用它来比较任何对象的值,但是我希望它忽略导航属性(其中包括忽略循环引用)。

foreach (var item in (IEnumerable)obj)
{
    list2.MoveNext();
    var item2 = list2.Current;
    foreach (PropertyInfo propInfo in item.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
    {
        Object v1 = propInfo.GetValue(item);
        Object v2 = propInfo.GetValue(item2);

        Primitive = (v1 == null && v2 == null) || IsPrimitive(v1.GetType());

        if (Primitive)
        {
            Assert.AreEqual(v1, v2);
        }
        else
        {
            // Ignore Navigation Properties
            // Currently assuming Virtual properties to be Navigation...
            if (propInfo.GetGetMethod().IsVirtual) continue;
            CompareObjects(v1, v2);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

oct*_*ccl 4

好吧,如果您想知道与实体相关的导航属性和标量属性的名称,我建议您使用以下代码:

using (var db = new YourContext())
{
    var workspace = ((IObjectContextAdapter)db).ObjectContext.MetadataWorkspace;
    var itemCollection = (ObjectItemCollection)(workspace.GetItemCollection(DataSpace.OSpace));
    var entityType = itemCollection.OfType<EntityType>().Single(e => itemCollection.GetClrType(e) == typeof(YourEntity));
    
    foreach (var navigationProperty in entityType.NavigationProperties)
    {
        Console.WriteLine(navigationProperty.Name);
    }
    
    foreach (var property in entityType.Properties)
    {
        Console.WriteLine(property.Name);
    }
}
Run Code Online (Sandbox Code Playgroud)