/// <summary> /// Tracks the AddRelatedObject method. /// </summary> /// <param name="data">The data service context data on which to apply state transition.</param> /// <param name="source">The source.</param> /// <param name="sourcePropertyName">Name of the source property.</param> /// <param name="target">The target.</param> public static void TrackAddRelatedObject(this DataServiceContextData data, object source, string sourcePropertyName, object target) { CheckEntityIsNotTracked(data, target); EntityDescriptorData sourceDescriptorData = GetTrackedEntityDescriptorData(data, source, "Cannot add link:", "source"); CheckStateIsNot(EntityStates.Deleted, sourceDescriptorData, "Cannot add related object:", "source"); EntityDescriptorData targetDescriptorData = data.CreateEntityDescriptorData(EntityStates.Added, data.GetNextChangeOrder(), target); data.CreateLinkDescriptorData(EntityStates.Added, uint.MaxValue, sourceDescriptorData, sourcePropertyName, targetDescriptorData); targetDescriptorData .SetParentForInsert(source) .SetParentPropertyForInsert(sourcePropertyName); }
/// <summary> /// Tracks the AttachLink method. /// </summary> /// <param name="data">The data service context data on which to apply state transition.</param> /// <param name="source">The source.</param> /// <param name="sourcePropertyName">Name of the source property.</param> /// <param name="target">The target.</param> public static void TrackAttachLink(this DataServiceContextData data, object source, string sourcePropertyName, object target) { ExceptionUtilities.CheckArgumentNotNull(data, "data"); LinkDescriptorData linkDescriptorData; if (data.TryGetLinkDescriptorData(source, sourcePropertyName, target, out linkDescriptorData)) { throw new TaupoInvalidOperationException( string.Format(CultureInfo.InvariantCulture, "The link already exists: {0}.", linkDescriptorData.ToString())); } EntityDescriptorData sourceDescriptorData = GetTrackedEntityDescriptorData(data, source, "Cannot attach link:", "source"); CheckStateIsNot(EntityStates.Deleted, sourceDescriptorData, "Cannot attach link:", "source"); CheckStateIsNot(EntityStates.Added, sourceDescriptorData, "Cannot attach link:", "source"); EntityDescriptorData targetDescriptorData = null; if (target != null) { targetDescriptorData = GetTrackedEntityDescriptorData(data, target, "Cannot attach link:", "target"); CheckStateIsNot(EntityStates.Deleted, targetDescriptorData, "Cannot attach link:", "target"); CheckStateIsNot(EntityStates.Added, targetDescriptorData, "Cannot attach link:", "target"); } data.CreateLinkDescriptorData(EntityStates.Unchanged, data.GetNextChangeOrder(), sourceDescriptorData, sourcePropertyName, targetDescriptorData); }
/// <summary> /// Tracks the SetLink method. /// </summary> /// <param name="data">The data service context data on which to apply state transition.</param> /// <param name="source">The source.</param> /// <param name="sourcePropertyName">Name of the source property.</param> /// <param name="target">The target.</param> public static void TrackSetLink(this DataServiceContextData data, object source, string sourcePropertyName, object target) { ExceptionUtilities.CheckStringArgumentIsNotNullOrEmpty(sourcePropertyName, "sourcePropertyName"); EntityDescriptorData sourceDescriptorData = GetTrackedEntityDescriptorData(data, source, "Cannot set link:", "source"); CheckStateIsNot(EntityStates.Deleted, sourceDescriptorData, "Cannot set link:", "source"); EntityDescriptorData targetDescriptorData = null; if (target != null) { targetDescriptorData = GetTrackedEntityDescriptorData(data, target, "Cannot set link:", "target"); CheckStateIsNot(EntityStates.Deleted, sourceDescriptorData, "Cannot set link:", "target"); } var relatedToSource = data.LinkDescriptorsData.Where(e => e.SourceDescriptor.Entity == source && e.SourcePropertyName == sourcePropertyName).ToList(); if (relatedToSource.Count > 1) { throw new TaupoInvalidOperationException("Cannot set link: source contains multiple links for the property: " + sourcePropertyName); } LinkDescriptorData existingLinkDescriptorData = relatedToSource.FirstOrDefault(); if (existingLinkDescriptorData == null) { data.CreateLinkDescriptorData(EntityStates.Modified, data.GetNextChangeOrder(), sourceDescriptorData, sourcePropertyName, targetDescriptorData); } else { if (existingLinkDescriptorData.State != EntityStates.Modified || existingLinkDescriptorData.TargetDescriptor != targetDescriptorData) { data.ChangeStateAndChangeOrder(existingLinkDescriptorData, EntityStates.Modified, data.GetNextChangeOrder()); } existingLinkDescriptorData.TargetDescriptor = targetDescriptorData; } }
/// <summary> /// Tracks the DeleteLink method. /// </summary> /// <param name="data">The data service context data on which to apply state transition.</param> /// <param name="source">The source.</param> /// <param name="sourcePropertyName">Name of the source property.</param> /// <param name="target">The target.</param> public static void TrackDeleteLink(this DataServiceContextData data, object source, string sourcePropertyName, object target) { EntityDescriptorData sourceDescriptorData = GetTrackedEntityDescriptorData(data, source, "Cannot delete link:", "source"); EntityDescriptorData targetDescriptorData = GetTrackedEntityDescriptorData(data, target, "Cannot delete link:", "target"); LinkDescriptorData descriptorData; if (data.TryGetLinkDescriptorData(sourceDescriptorData, sourcePropertyName, targetDescriptorData, out descriptorData) && descriptorData.State == EntityStates.Added) { data.RemoveDescriptorData(descriptorData); } else { CheckStateIsNot(EntityStates.Added, sourceDescriptorData, "Cannot delete link:", "source"); CheckStateIsNot(EntityStates.Added, targetDescriptorData, "Cannot delete link:", "target"); if (descriptorData == null) { data.CreateLinkDescriptorData(EntityStates.Deleted, data.GetNextChangeOrder(), sourceDescriptorData, sourcePropertyName, targetDescriptorData); } else if (descriptorData.State != EntityStates.Deleted) { data.ChangeStateAndChangeOrder(descriptorData, EntityStates.Deleted, data.GetNextChangeOrder()); } } }
/// <summary> /// Extension method to either find or create a link descriptor with the given values /// </summary> /// <param name="contextData">The context data</param> /// <param name="sourceDescriptor">The source descriptor</param> /// <param name="propertyName">The property name</param> /// <param name="targetDescriptor">The target descriptor</param> /// <returns>A link descriptor with the given values</returns> public static LinkDescriptorData MaterializeLinkDescriptor(this DataServiceContextData contextData, EntityDescriptorData sourceDescriptor, string propertyName, EntityDescriptorData targetDescriptor) { var existingLink = contextData.LinkDescriptorsData.SingleOrDefault(l => l.SourceDescriptor == sourceDescriptor && l.SourcePropertyName == propertyName && l.TargetDescriptor == targetDescriptor); if (existingLink == null) { existingLink = contextData.CreateLinkDescriptorData(EntityStates.Unchanged, 0, sourceDescriptor, propertyName, targetDescriptor); } return existingLink; }