Entity Framework 6 ChangeTracker entries are all unchanged despite removing an entity from a navigation collection

c# entity-framework entity-framework-6

Question

I'm overriding my DbContext SaveChanges method and capturing the ChangeTracker entries.

public override int SaveChanges()
{
    var entries = ChangeTracker.Entries();
    return base.SaveChanges();
}

I have an entity called "Range" that has a navigation property to another entity called "Feature"

public class Range
{
    //other code
    public virtual ICollection<Feature> Features { get; set; }
}

I'm removing a feature from the range and then saving the changes

var featureToRemove = range.Features.First(f => f.ID == featureId);
range.Features.Remove(featureToRemove);
centralProducts.SaveChanges();

After calling this code the feature is successfully removed but the entries in the ChangeTracker all have an EntityStatus of Unchanged (not just the range entity in question).

Something is changing or the database would not be updated.

Is there any way to capture this change in the SaveChanges method? Is Unchanged really the status I would expect to see when removing something from a navigation property?

I am aware that the table that actually gets changed is called Range_Features, and is neither the Range nor the Feature itself.

1
2
7/1/2019 9:14:54 AM

Accepted Answer

As already stated, the EF does track changes to relationships. I was able to capture these changes using the following extension methods

public static class IaExtensions
{
    public static IEnumerable<Tuple<object, object>> GetAddedRelationships(
    this DbContext context)
    {
        return GetRelationships(context, EntityState.Added, (e, i) => e.CurrentValues[i]);
    }

    public static IEnumerable<Tuple<object, object>> GetDeletedRelationships(
    this DbContext context)
    {
        return GetRelationships(context, EntityState.Deleted, (e, i) => e.OriginalValues[i]);
    }

    private static IEnumerable<Tuple<object, object>> GetRelationships(
    this DbContext context,
    EntityState relationshipState,
    Func<ObjectStateEntry, int, object> getValue)
    {
        context.ChangeTracker.DetectChanges();
        var objectContext = ((IObjectContextAdapter)context).ObjectContext;

        return objectContext
        .ObjectStateManager
        .GetObjectStateEntries(relationshipState)
        .Where(e => e.IsRelationship)
        .Select(
            e => Tuple.Create(
                objectContext.GetObjectByKey((EntityKey)getValue(e, 0)),
                objectContext.GetObjectByKey((EntityKey)getValue(e, 1))));
    }
}

See this answer for more details

1
7/1/2019 2:36:31 PM

Popular Answer

EF tracks changes to both Entities and Relationships, but DbContext only has an API to display the change tracking entries for Entities. When you change a relationship it will be implemented by either an UPDATE or a DELETE, depending on the kind of relationship.

But yes, in this scenario, both the Entities participating in the Many to Many relationship are unchanged.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow