Efcore: Detecting changes to shadow properties

Created on 14 Oct 2020  路  4Comments  路  Source: dotnet/efcore

I'm working on a project where it's important to instantly detect any change made to any tracked entity. With change-tracking proxies, INotifyPropertyChanged.PropertyChanged and EF events, it's easy to instantly detect state and property changes. The only problem for me is shadow properties. I couldn't find a way to detect when a change is made to a shadow property of an entity that's Added/Modified/Deleted. I thought about value comparators/converters but they are part of the model and creating a unique model per context wouldn't be practical.

Is there any option other than forking the codebase?

closed-question customer-reported

All 4 comments

Can you elaborate on how would you use these events?

EF doesn't track property changes on Added and Deleted entities.

To find the modified shadow properties you can do this:

```C#
context.ChangeTracker.DetectChanges();

foreach (var entry in context.ChangeTracker.Entries())
{
if (entry.State != EntityState.Modified)
{
continue;
}

foreach (var propertyEntry in entry.Properties)
{
    if (!propertyEntry.IsModified
        || !propertyEntry.Metadata.IsShadowProperty())
    {
        continue;
    }

    // TODO: react to property change
}

}

// This avoids the extra DetectChanges in SaveChanges
context.ChangeTracker.AutoDetectChangesEnabled = false;

context.SaveChanges();
```

This could be done in 'DetectChangesCompleted' when https://github.com/dotnet/efcore/issues/16256 is implemented

@AndriySvyryd
Thanks for your response

Can you elaborate on how would you use these events?

1) For safety reasons, I need to able to temporarily "freeze" the context such that any state/property change instantly causes an exception.
I'm able to instantly detect all possible state/property changes except changes to shadow properties that are not foreign keys and belong to entities that are Added/Modified/Deleted.

2) I need to perform some actions when a foreign key is changed in the context. The CoreEventId.ForeignKeyChangeDetectedis fired even for shadow properties of entities that are Added/Modified/Deleted I but can't know the affected shadow property without enabling sensitive data logging which has an overhead.

EF doesn't track property changes on Added and Deleted entities.

That's why I'm using INotifyPropertyChanged.PropertyChanged event (with change-tracking proxies).

I managed to do exactly what I want using internals and reflection.

Thanks for writing highly readable code. Feel free to close the issue.

Glad it worked out. In 5.0 consider using indexer properties instead of shadow properties.

Was this page helpful?
0 / 5 - 0 ratings