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

Exclude specific property from change tracking #19461

Open
Tracked by #22954
edwardaskew opened this issue Jan 2, 2020 · 3 comments
Open
Tracked by #22954

Exclude specific property from change tracking #19461

edwardaskew opened this issue Jan 2, 2020 · 3 comments

Comments

@edwardaskew
Copy link

I have an entity with a geometry column which causes SaveChanges to take a long time (>1min) whenever the entities are tracked - presumably due to having to compare geometries to determine whether they have changed. Due to other areas of the project making use of lazy loading, I can't turn change tracking off globally and so I have to make sure to use AsNoTracking everywhere this particular entity type is used (including queries that Include them) which is proving a bit of a pain. I tried setting Metadata.AfterSaveBehaviour to PropertySaveBehaviour.Ignore but this seems to still attempt to track changes to the property even though it would then (I believe) ignore any changes it found.

Is there any way to exclude the particular property from change tracking? If AfterSaveBehaviour set to Ignore worked as one might expect this would be a start but ideally there should be some way of excluding the property in standard change tracking but still allow it to be manually mark as modified (using IsModified which I assume (although I haven't tested this) would still cause a property to be ignore when setting AfterSaveBehaviour).

@ajcvickers
Copy link
Member

@edwardaskew This can be done by setting a custom ValueComparer for the properties which always indicates that the value has not changed. For example:

var valueComparer = new ValueComparer<Point>(
    (x, y) => true,
    v => v.GetHashCode(),
    v => (Point)v.Copy());

modelBuilder
    .Entity<Blog>()
    .Property(e => e.Location)
    .Metadata.SetValueComparer(valueComparer);

EF will then never mark the property has modified, but it can still be explicitly marked as modified which will be picked up by SaveChanges.

See also: #18643

@ajcvickers
Copy link
Member

Putting this on the backlog to consider making this more first class. Open question: can reference equality be used safely without snapshotting? Consider #14042 and #19417 where snapshotting was important to fix bugs.

@jlchavez
Copy link

I would up vote on converting these to a first class, because doing this on a lot of columns, even if it is one column on every table, it's a lot of code for maintaining and means bloating the code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants