我正在重写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本身。
答案 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