尽管从导航集合中删除了实体,实体框架6的ChangeTracker条目都保持不变

时间:2019-07-01 09:02:56

标签: c# entity-framework entity-framework-6

我正在重写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都为Unchanged(不仅仅是所讨论的范围实体)。

某些事情正在改变,或者数据库将不会更新。

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

我知道实际上被更改的表称为Range_Features,既不是Range也不是Feature本身。

2 个答案:

答案 0 :(得分:1)

EF跟踪对实体和关系的更改,但是DbContext仅具有一个API以显示实体的更改跟踪条目。更改关系时,将根据关系的类型通过UPDATE或DELETE来实现。

但是,是的,在这种情况下,参与多对多关系的两个实体都保持不变。

答案 1 :(得分:1)

如上所述,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