protected override string GetUnregisterProblem(IRelationEndPoint endPoint, RelationEndPointMap relationEndPointMap) { ArgumentUtility.CheckNotNull("endPoint", endPoint); ArgumentUtility.CheckNotNull("relationEndPointMap", relationEndPointMap); // An end-point must be unchanged to be unregisterable. if (endPoint.HasChanged) { return(string.Format( "Relation end-point '{0}' has changed. Only unchanged relation end-points can be unregistered.", endPoint.ID)); } // If it is a real object end-point pointing to a non-null object, and the opposite end-point is loaded, the opposite (virtual) end-point // must be unchanged. Virtual end-points cannot exist in changed state without their opposite real end-points. // (This only affects 1:n relations: for those, the opposite virtual end-point can be changed although the (one of many) real end-point is // unchanged. For 1:1 relations, the real and virtual end-points always have an equal HasChanged flag.) var maybeOppositeEndPoint = Maybe .ForValue(endPoint as IRealObjectEndPoint) .Select(ep => RelationEndPointID.CreateOpposite(ep.Definition, ep.OppositeObjectID)) .Select(oppositeEndPointID => relationEndPointMap[oppositeEndPointID]); if (maybeOppositeEndPoint.Where(ep => ep.HasChanged).HasValue) { return(string.Format( "The opposite relation property '{0}' of relation end-point '{1}' has changed. Non-virtual end-points that are part of changed relations " + "cannot be unloaded.", maybeOppositeEndPoint.Value().Definition.PropertyName, endPoint.ID)); } return(null); }
public override void Synchronize() { var oppositeID = RelationEndPointID.CreateOpposite(Definition, OppositeObjectID); var oppositeEndPoint = (IVirtualEndPoint)_endPointProvider.GetRelationEndPointWithLazyLoad(oppositeID); _syncState.Synchronize(this, oppositeEndPoint); }
protected virtual void UnregisterOppositeForRealObjectEndPoint(IRealObjectEndPoint realObjectEndPoint, RelationEndPointMap map) { ArgumentUtility.CheckNotNull("realObjectEndPoint", realObjectEndPoint); ArgumentUtility.CheckNotNull("map", map); var oppositeEndPointID = RelationEndPointID.CreateOpposite(realObjectEndPoint.Definition, realObjectEndPoint.OriginalOppositeObjectID); if (oppositeEndPointID.Definition.IsAnonymous) { realObjectEndPoint.ResetSyncState(); return; } var oppositeEndPoint = _virtualEndPointProvider.GetOrCreateVirtualEndPoint(oppositeEndPointID); if (oppositeEndPoint == null) { var message = string.Format( "Opposite end-point of '{0}' not found. When unregistering a non-virtual bidirectional end-point, the opposite end-point must exist.", realObjectEndPoint.ID); throw new InvalidOperationException(message); } oppositeEndPoint.UnregisterOriginalOppositeEndPoint(realObjectEndPoint); if (oppositeEndPoint.CanBeCollected) { map.RemoveEndPoint(oppositeEndPoint.ID); } }
protected virtual IVirtualEndPoint RegisterOppositeForRealObjectEndPoint(IRealObjectEndPoint realObjectEndPoint) { ArgumentUtility.CheckNotNull("realObjectEndPoint", realObjectEndPoint); var oppositeVirtualEndPointID = RelationEndPointID.CreateOpposite(realObjectEndPoint.Definition, realObjectEndPoint.OriginalOppositeObjectID); if (oppositeVirtualEndPointID.Definition.IsAnonymous) { realObjectEndPoint.MarkSynchronized(); return(null); } var oppositeVirtualEndPoint = _virtualEndPointProvider.GetOrCreateVirtualEndPoint(oppositeVirtualEndPointID); oppositeVirtualEndPoint.RegisterOriginalOppositeEndPoint(realObjectEndPoint); return(oppositeVirtualEndPoint); }