Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detecting changes to shadow properties #22991

Closed
mnver1 opened this issue Oct 14, 2020 · 4 comments
Closed

Detecting changes to shadow properties #22991

mnver1 opened this issue Oct 14, 2020 · 4 comments
Labels
closed-no-further-action The issue is closed and no further action is planned. customer-reported

Comments

@mnver1
Copy link

mnver1 commented Oct 14, 2020

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?

@AndriySvyryd
Copy link
Member

AndriySvyryd commented Oct 17, 2020

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:

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 #16256 is implemented

@mnver1
Copy link
Author

mnver1 commented Oct 19, 2020

@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.ForeignKeyChangeDetected is 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).

@mnver1
Copy link
Author

mnver1 commented Oct 24, 2020

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

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

@AndriySvyryd
Copy link
Member

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

@ajcvickers ajcvickers added the closed-no-further-action The issue is closed and no further action is planned. label Oct 26, 2020
@ajcvickers ajcvickers reopened this Oct 16, 2022
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-no-further-action The issue is closed and no further action is planned. customer-reported
Projects
None yet
Development

No branches or pull requests

3 participants