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); }
protected override string GetUnregisterProblem(IRelationEndPoint endPoint, RelationEndPointMap relationEndPointMap) { ArgumentUtility.CheckNotNull("endPoint", endPoint); ArgumentUtility.CheckNotNull("relationEndPointMap", relationEndPointMap); var objectEndPoint = endPoint as IObjectEndPoint; if (objectEndPoint != null) { if (objectEndPoint.OppositeObjectID == null && objectEndPoint.OriginalOppositeObjectID == null) { return(null); } } else { var collectionEndPoint = (ICollectionEndPoint)endPoint; if (collectionEndPoint.GetData().Count == 0 && collectionEndPoint.GetOriginalData().Count == 0) { return(null); } } return(string.Format("Relation end-point '{0}' would leave a dangling reference.", endPoint.ID)); }
public void RegisterEndPoints(DataContainer dataContainer, RelationEndPointMap relationEndPointMap) { ArgumentUtility.CheckNotNull("dataContainer", dataContainer); ArgumentUtility.CheckNotNull("relationEndPointMap", relationEndPointMap); var agent = ChooseAgent(dataContainer); agent.RegisterEndPoints(dataContainer, relationEndPointMap); }
protected RelationEndPointManager(FlattenedDeserializationInfo info) { ArgumentUtility.CheckNotNull("info", info); _clientTransaction = info.GetValueForHandle <ClientTransaction>(); _lazyLoader = info.GetValueForHandle <ILazyLoader>(); _endPointFactory = info.GetValueForHandle <IRelationEndPointFactory>(); _registrationAgent = info.GetValueForHandle <IRelationEndPointRegistrationAgent> (); _map = info.GetValue <RelationEndPointMap> (); _dataContainerEndPointsRegistrationAgent = new DelegatingDataContainerEndPointsRegistrationAgent(_endPointFactory, _registrationAgent); }
public void RegisterEndPoints(DataContainer dataContainer, RelationEndPointMap relationEndPointMap) { ArgumentUtility.CheckNotNull("dataContainer", dataContainer); ArgumentUtility.CheckNotNull("relationEndPointMap", relationEndPointMap); foreach (var id in GetOwnedEndPointIDs(dataContainer)) { var endPoint = id.Definition.IsVirtual ? (IRelationEndPoint)_endPointFactory.CreateVirtualEndPoint(id, true) : _endPointFactory.CreateRealObjectEndPoint(id, dataContainer); _registrationAgent.RegisterEndPoint(endPoint, relationEndPointMap); } }
public void UnregisterEndPoint(IRelationEndPoint endPoint, RelationEndPointMap map) { ArgumentUtility.CheckNotNull("endPoint", endPoint); ArgumentUtility.CheckNotNull("map", map); if (map[endPoint.ID] != endPoint) { var message = string.Format("End-point '{0}' is not part of this map.\r\nParameter name: endPoint", endPoint.ID); throw new ArgumentException(message); } var realObjectEndPoint = endPoint as IRealObjectEndPoint; if (realObjectEndPoint != null) { UnregisterOppositeForRealObjectEndPoint(realObjectEndPoint, map); } map.RemoveEndPoint(endPoint.ID); }
public void RegisterEndPoint(IRelationEndPoint endPoint, RelationEndPointMap map) { ArgumentUtility.CheckNotNull("endPoint", endPoint); ArgumentUtility.CheckNotNull("map", map); if (map[endPoint.ID] != null) { var message = string.Format("A relation end-point with ID '{0}' has already been registered.", endPoint.ID); throw new InvalidOperationException(message); } map.AddEndPoint(endPoint); var realObjectEndPoint = endPoint as IRealObjectEndPoint; if (realObjectEndPoint != null) { RegisterOppositeForRealObjectEndPoint(realObjectEndPoint); } }
public RelationEndPointManager( ClientTransaction clientTransaction, ILazyLoader lazyLoader, IClientTransactionEventSink transactionEventSink, IRelationEndPointFactory endPointFactory, IRelationEndPointRegistrationAgent registrationAgent) { ArgumentUtility.CheckNotNull("clientTransaction", clientTransaction); ArgumentUtility.CheckNotNull("lazyLoader", lazyLoader); ArgumentUtility.CheckNotNull("transactionEventSink", transactionEventSink); ArgumentUtility.CheckNotNull("endPointFactory", endPointFactory); ArgumentUtility.CheckNotNull("registrationAgent", registrationAgent); _clientTransaction = clientTransaction; _lazyLoader = lazyLoader; _endPointFactory = endPointFactory; _registrationAgent = registrationAgent; _dataContainerEndPointsRegistrationAgent = new DelegatingDataContainerEndPointsRegistrationAgent(endPointFactory, registrationAgent); _map = new RelationEndPointMap(transactionEventSink); }
public IDataManagementCommand CreateUnregisterEndPointsCommand(DataContainer dataContainer, RelationEndPointMap relationEndPointMap) { ArgumentUtility.CheckNotNull("dataContainer", dataContainer); ArgumentUtility.CheckNotNull("relationEndPointMap", relationEndPointMap); var loadedEndPoints = new List <IRelationEndPoint>(); var problems = new List <string>(); foreach (var endPointID in GetOwnedEndPointIDs(dataContainer)) { var endPoint = relationEndPointMap[endPointID]; if (endPoint != null) { loadedEndPoints.Add(endPoint); var problem = GetUnregisterProblem(endPoint, relationEndPointMap); if (problem != null) { problems.Add(problem); } } } if (problems.Count > 0) { var message = string.Format( "The relations of object '{0}' cannot be unloaded." + Environment.NewLine + "{1}", dataContainer.ID, string.Join(Environment.NewLine, problems)); return(new ExceptionCommand(new InvalidOperationException(message))); } else { return(new UnregisterEndPointsCommand(loadedEndPoints, _registrationAgent, relationEndPointMap)); } }
protected abstract string GetUnregisterProblem(IRelationEndPoint endPoint, RelationEndPointMap relationEndPointMap);
public IDataManagementCommand CreateUnregisterEndPointsCommand(DataContainer dataContainer, RelationEndPointMap relationEndPointMap) { ArgumentUtility.CheckNotNull("dataContainer", dataContainer); ArgumentUtility.CheckNotNull("relationEndPointMap", relationEndPointMap); var agent = ChooseAgent(dataContainer); return(agent.CreateUnregisterEndPointsCommand(dataContainer, relationEndPointMap)); }
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); } }