Mark Olbert Mark Olbert - 1 month ago 11
C# Question

Determine if property is a Navigation Property in EF Core

I'm building a simple change tracker to capture all the edits to a Sql Azure database (unfortunately, Sql Azure doesn't support this natively, so far as I can tell).

I'm walking the list of modified entries returned by ChangeTracker():

foreach( EntityEntry entry in _context.ChangeTracker.Entries()
.Where( e => e.State == EntityState.Modified ) )
{
foreach( var prop in entry.Entity
.GetType()
.GetTypeInfo()
.DeclaredProperties )
{
// this line blows up on navigation properties
PropertyEntry propEntry = entry.Property( prop.Name );

if( propEntry.IsModified )
{
var curValue = entry.Property( prop.Name ).CurrentValue;
var origValue = entry.Property( prop.Name ).OriginalValue;
}
}
}


Unfortunately, retrieving the PropertyEntry info for a property blows up -- InvalidOperationException -- when the property is a navigation property, claiming the property can't be found.

I could just wrap the code in an try/catch block...but I'm curious if there's another way to determine, perhaps from metadata, that a property is a navigation or related property.

Answer

Rather than using reflection

foreach (var prop in entry.Entity.GetType().GetTypeInfo().DeclaredProperties)

you can use the metadata provided by the EntityEntry.Metadata property:

foreach (var prop in entry.Metadata.GetProperties())

Note that the IEntityType returned by the Metadata property has separate methods for simple properties (GetProperties method) and navigation properties (GetNavigations extension method).

Comments