Entity Framework 尽管从导航集合中删除了一个实体,但 6 个 ChangeTracker 条目都没有改变

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

我正在覆盖我的 DbContext SaveChanges 方法并捕获 ChangeTracker 条目。

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

我有一个名为 "Range" 的实体,它具有指向另一个名为 "Feature"

的实体的导航 属性
public class Range
{
    //other code
    public virtual ICollection<Feature> Features { get; set; }
}

我要从范围中删除一项功能,然后保存更改

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

调用此代码后,该功能已成功删除,但 ChangeTracker 中的条目的 EntityStatus 均为未更改(不仅仅是相关范围实体)。

有些事情正在发生变化,或者数据库不会更新。

有什么方法可以在 SaveChanges 方法中捕获此更改?从导航中删除某些内容时,Unchanged 真的是我希望看到的状态吗?属性?

我知道实际更改的 table 称为 Range_Features,既不是范围也不是特征本身。

EF 跟踪对实体和关系的更改,但 DbContext 只有一个 API 来显示实体的更改跟踪条目。当您更改关系时,它将通过 UPDATE 或 DELETE 实现,具体取决于关系的类型。

但是,是的,在这种情况下,参与多对多关系的两个实体都没有改变。

如前所述,EF 会跟踪关系的变化。我能够使用以下扩展方法捕获这些更改

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))));
    }
}

有关详细信息,请参阅 this answer