这里有几个有趣的点。EntityFramework 独立于实体的更改跟踪导航属性的更改。context.ChangeTracker.Entries() 仅返回对实体的更改,而不是对关系的更改。这就是你看不到这些的原因。如果您真的想查看关系以及它们如何变化,您可以下拉到 ObjectContext 并执行以下操作:
var objectContext = ((IObjectContextAdapter) ctx).ObjectContext;
foreach(var relationshipEntry in objectContext.ObjectStateManager
.GetObjectStateEntries(EntityState.Added | EntityState.Modified | EntityState.Deleted)
.Where(e => e.IsRelationship))
{
EntityKey entityKey1, entityKey2;
if (relationshipEntry.State == EntityState.Added)
{
entityKey1 = (EntityKey)relationshipEntry.CurrentValues[0];
entityKey2 = (EntityKey)relationshipEntry.CurrentValues[1];
}
else
{
entityKey1 = (EntityKey)relationshipEntry.OriginalValues[0];
entityKey2 = (EntityKey)relationshipEntry.OriginalValues[1];
}
var entity1 = objectContext.GetObjectByKey((EntityKey)entityKey1);
var entity2 = objectContext.GetObjectByKey((EntityKey)entityKey2);
}
对我来说更有趣的场景是当关系发生变化时需要重新验证实体的场景。我假设您没有外键 - 否则您的实体将被标记为已修改,因为更改导航属性会更改外键的值,这反过来会将实体标记为已修改。无论如何,鉴于我有三个有效实体 - 改变关系可能使实体(或模型)无效的情况是什么?另外,请注意,验证本身仅验证给定实体,但从不遵循导航属性来验证相关实体。最后,如果您真的需要在关系发生变化时验证实体,我认为您有 4 个选项:
protected override bool ShouldValidateEntity(DbEntityEntry entityEntry)
{
return (entityEntry.State & EntityState.Deleted) == 0;
}
您可以在此处找到有关验证和验证自定义的更多详细信息:
http: //blogs.msdn.com/b/adonet/archive/2010/12/15/ef-feature-ctp5-validation.aspx
http://blogs.msdn .com/b/adonet/archive/2011/05/27/ef-4-1-validation.aspx(是的,它适用于 CTP 和 EF 4.1,但仍然有效)