在处理分离的实体,尤其是实体图时,在处理对现有数据的任何引用时,都需要格外小心。在一个更改中,您有将被添加的ChangeStatus条目,但每个更改状态都引用一个ChangeStatusType,这是一组有限的现有值。保存单个状态时,您可能会附加其状态类型,或者最终尝试插入新的状态类型。当插入两个状态时,只要状态具有不同的状态类型,它就可以工作,但否则会出现跟踪参考问题。
foreach (var change in addedChanges)
{
// Change.ChangeStatuses will already be treated as "Added" but we don't want references to be treated as Add.
foreach (var changeStatus in change.ChangeStatuses)
{
//context.ChangeTracker.TrackGraph(changeStatus, x => { x.Entry.State = EntityState.Added; });
var existingStatusType = context.StatusType.Local
.FirstOrDefault(x => x.StatusTypeId == changeStatus.StatusTypes.StatusTypeId);
if (existingStatusType != null)
changeStatus.StatusTypes = existingStatusType
else
context.Attach(changeStatus.StatusTypes);
}
// Edit: yes, the reference updates need to be done before adding the parent..
context.Changes.Add(change);
}
本质上,这里的区别在于,我们不想将整个图视为已添加。添加更改时,ChangeStatues将自动被视为已添加,这是我们想要的,但我们不想要状态。StatusTypes被视为已添加。相反,我们根据
.Local
跟踪缓存,如果找到,则将引用替换为跟踪状态。如果它没有被跟踪,那么我们通过附加来跟踪它。当我们进入下一个更改状态时,当检查状态类型是否匹配时,它将解析跟踪的引用。