繁体   English   中英

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

[英]How to distinguish Navigation Properties from regular ones when using GetProperties?

有没有办法区分Entity-Framework类(Database-First)上的常规集合属性和导航属性?

我目前正在检查对象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);
        }
    }
}

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

 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);
   }
}

使用GetProperties()时的一个解决方案是创建IEntity接口并将其应用于所有实体。 然后,您可以通过检查它们是否实现IEntity和多个实体导航(如果它们是ICollection类型)来跳过单个实体导航属性。

所以在你的foreach中,

if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(System.Collections.Generic.ICollection<>)) continue;
if (property.PropertyType.GetInterfaces().Contains(typeof(IEntity))) continue;

这是一个使用此逻辑仅返回可更新属性的简单方法:

private IEnumerable<PropertyInfo> GetUpdateableProperties<T>(T entity) where T : IEntity
    {
        return entity.GetType().GetProperties(BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty)
            .Where(property =>
                property.CanWrite &&
                !property.PropertyType.GetInterfaces().Contains(typeof(IEntity)) &&
                !(property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(ICollection<>))
                );
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM