Определить, является ли свойство свойством навигации в ядре EF

#c# #entity-framework-core

#c# #entity-framework-core

Вопрос:

Я создаю простой трекер изменений для сбора всех изменений в базе данных Sql Azure (к сожалению, Sql Azure не поддерживает это изначально, насколько я могу судить).

Я просматриваю список измененных записей, возвращаемых 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;
        }
    }
}
  

К сожалению, получение информации о свойстве для свойства приводит к сбою — InvalidOperationException — когда свойство является свойством навигации, утверждая, что свойство не может быть найдено.

Я мог бы просто обернуть код в блок try / catch … но мне любопытно, есть ли другой способ определить, возможно, из метаданных, что свойство является навигационным или связанным свойством.

Ответ №1:

Вместо использования отражения

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

вы можете использовать метаданные, предоставленные EntityEntry.Metadata свойством:

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

Обратите внимание, что IEntityType возвращаемое Metadata свойство имеет отдельные методы для простых свойств ( GetProperties метод) и свойств навигации ( GetNavigations метод расширения).