Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Is there a way to distinguish between a regular collection property and a navigation property on an Entity-Framework class (Database-First)?

I'm currently checking if the object is ICollection and IsVirtual but I feel this could possibly trigger on a regular property that someone has declared as a virtual collection.

Question: Are there any other ways to distinguish Navigation Properties from others?

Context: I'm using this to compare values of any object, but I want it to ignore navigation properties (to ignore circular-references among other things).

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);
        }
    }
}
like image 446
Shelby115 Avatar asked Feb 09 '15 14:02

Shelby115


People also ask

What are the properties of the navigation?

Navigation properties allow you to navigate and manage relationships in both directions, returning either a reference object (if the multiplicity is either one or zero-or-one) or a collection (if the multiplicity is many).

How do I get a property type from PropertyInfo?

You can do this by getting an array of all properties from the Type. GetProperties method and then iterating the elements in the array, or you can retrieve the PropertyInfo object that represents the property directly by calling the Type. GetProperty method and specifying the property name.

Why navigation properties are virtual?

Navigation properties are typically defined as virtual so that they can take advantage of certain Entity Framework functionality such as lazy loading.


1 Answers

Well, if you want to know the names of the navigation properties and the scalar properties related to an Entity, I suggest you use this code:

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);
    }
}
like image 174
octavioccl Avatar answered Sep 30 '22 18:09

octavioccl