Entity Framework Core - Как я могу динамически регистрировать изменения свойств связанных сущностей во время SaveChanges, используя общий метод? - PullRequest
0 голосов
/ 05 июня 2018

Недавно я изучал EF Core на основе Audit ChangeLog, где я нашел большую часть ресурсов, которые отслеживают журнал как прямое свойство сущности, используя отражение, предположим, у меня есть две связанные сущности:

public Class Order
{
    public int OrderId {get; set;}
    public int OrderName {get; set;}
    public virtual Collection<OrderDetail> OrderDetails { get; set; } = new Collection<OrderDetail>();
}
public Class OrderDetail
{
    public int OrderDetailId {get; set;}
    public int OrderDetailName {get; set;}
    public int OrderDetailQuantity {get; set;}
    public int? OrderID { get; set; }
    public virtual Order OrderFk { get; set; }
}

Тогда мой TrackChange будет выглядеть следующим образом:

protected virtual IEnumerable<ChangeLog> TrackChange()
{
    foreach (var entry in DbContext.ChangeTracker.Entries())
    {  
        var entityType = entry.Entity.GetType();

        foreach (var property in entityType.GetTypeInfo().DeclaredProperties)
        {
            var originalValue = entry.Property(property.Name).OriginalValue;
            var currentValue = entry.Property(property.Name).CurrentValue;

            //Log if originalValue != currentValue 
        }
    }
}

Поэтому, если у меня есть Order, содержащий 3 OrderDetails, тогда я изменяю Name Order и один из OrderDetail, обновляя OrderDetailQuantity. и сохранить как Order, TrackChange перехватит мое изменение OrderName, так как это свойство Order, но , когда «свойство в entityType.GetTypeInfo (). DeclaredProperties» становится «OrderDetails» , это делаетне достаточно умен, чтобы обнаружить, что это коллекция или связанная сущность «Порядка», тогда я получаю исключение при попытке получить originalValue, говоря:

'The property 'OrderDetails' on entity type 'Order' is being accessed using the 'Property' method, but is defined in the model as a navigation property. Use either the 'Reference' or 'Collection' method to access navigation properties.'

Я знаю, что, вероятно, могу использовать entry.Collection (свойство.Имя), чтобы перейти в коллекцию "OrderDetail", но вопрос будет: Откуда мне знать, что текущая собственностьy является типом значения типа Int / String / Datetime, хотя он также может быть связанной сущностью или коллекцией текущей записи?

Другие мысли о TrackChange и ниже - моя идея псевдокода:

function TrackChange(Entity)
   //Track Base Entity Change
   ...
   //Track Child Entity Change if there is any
   if (Entity.HasChildNode) 
   {
      foreach(ChildEntity of Entity.ChildEntities)
           TrackChange(ChildEntity);
   }
   ...
}

Поскольку мой TrackChange является универсальным, поэтому я надеюсь, что есть способ реализовать вышеуказанную идею, используя отражение C #.

...