/// <summary> /// Removes the the entity with the given key from the given the given property on the given structural value /// </summary> /// <param name="keyToRemove">The key of the entity to remove</param> /// <param name="related">The structural value to remove from</param> /// <param name="navigation">The property to remove from</param> private void RemoveFromNavigationProperty(EntityDataKey keyToRemove, QueryStructuralValue related, NavigationProperty navigation) { if (navigation.ToAssociationEnd.Multiplicity == EndMultiplicity.Many) { var collection = related.GetCollectionValue(navigation.Name); // remove the element with the given key from the collection, if it is present foreach (var element in collection.Elements.Cast <QueryStructuralValue>().ToList()) { if (this.GetEntityKey(element).Equals(keyToRemove)) { collection.Elements.Remove(element); } } } else { // if the value's key matches, set it to null var value = related.GetStructuralValue(navigation.Name); if (!value.IsNull && this.GetEntityKey(value).Equals(keyToRemove)) { related.SetValue(navigation.Name, value.Type.NullValue); } } }
/// <summary> /// Initializes a new instance of the <see cref="RelationshipDescription"/> class. /// </summary> /// <param name="associationSet">The association set.</param> /// <param name="from">EntityDataKey for the 'from' end.</param> /// <param name="toRoleName">Role name for the 'to' end</param> /// <param name="to">EntityDataKey for the 'to' end.</param> public RelationshipDescription(AssociationSet associationSet, EntityDataKey from, string toRoleName, EntityDataKey to) { this.AssociationSet = associationSet; this.From = from; this.ToRoleName = toRoleName; this.To = to; this.FromRoleName = this.AssociationSet.Ends.Where(e => e.AssociationEnd.RoleName != toRoleName).Single().AssociationEnd.RoleName; }
/// <summary> /// Initializes a new instance of the <see cref="RelationshipCandidate"/> class. /// </summary> /// <param name="parent">The parent relationship group end this candidate can be used for.</param> /// <param name="entityDataKey">The entity data key.</param> /// <param name="capacityRange">The capacity range.</param> public RelationshipCandidate( RelationshipGroupEnd parent, EntityDataKey entityDataKey, CapacityRange capacityRange) { this.EntityDataKey = entityDataKey; this.CapacityRange = capacityRange; this.Parent = parent; }
/// <summary> /// Gets the related keys for the given roleName in an association(denoted by associationSetName), given this end's key. /// </summary> /// <param name="data">The EntityContainerData which contains AssociationSetData.</param> /// <param name="associationSetName">The name of the association set.</param> /// <param name="roleName">The roleName of the known end.</param> /// <param name="roleKey">The key for the role of the known end.</param> /// <returns>The Related keys of the other end.</returns> public static IEnumerable<EntityDataKey> GetRelatedKeys(this EntityContainerData data, string associationSetName, string roleName, EntityDataKey roleKey) { ExceptionUtilities.CheckArgumentNotNull(data, "data"); ExceptionUtilities.CheckStringArgumentIsNotNullOrEmpty(associationSetName, "associationSetName"); ExceptionUtilities.CheckStringArgumentIsNotNullOrEmpty(roleName, "roleName"); ExceptionUtilities.CheckArgumentNotNull(roleKey, "roleKey"); var associationSetData = data.GetAssociationSetData(associationSetName); string otherRoleName = associationSetData.AssociationSet.AssociationType.Ends.Where(e => e.RoleName != roleName).Single().RoleName; return associationSetData.Rows.Where(r => roleKey.Equals(r.GetRoleKey(roleName))).Select(r => r.GetRoleKey(otherRoleName)); }
/// <summary> /// Gets the EntityDataKey for the specified association role. /// </summary> /// <param name="roleName">The association role name.</param> /// <returns>EntityDataKey for the association role.</returns> public EntityDataKey GetRoleKey(string roleName) { int ordinal = this.GetRoleNameOrdinal(roleName); EntityDataKey key = this.data[ordinal]; if (key == null) { key = new EntityDataKey(this.GetKeyNamesForRoleName(roleName)); this.data[ordinal] = key; } return key; }
/// <summary> /// Considers the candidate for this relationship. /// </summary> /// <param name="entitySet">The entity set.</param> /// <param name="entityType">Type of the entity.</param> /// <param name="key">The entity data key of the candidate.</param> public void ConsiderCandidate(EntitySet entitySet, EntityType entityType, EntityDataKey key) { foreach (RelationshipGroupEnd end in this.ends.Where(e => e.EntitySet == entitySet && entityType.IsKindOf(e.EntityType))) { CapacityRange capacityRange = end.CapacitySelector(); if (capacityRange != CapacityRange.Zero) { this.RemoveCandidatesOnTargetBasedOnTreshhold(end); RelationshipCandidate candidate = new RelationshipCandidate(end, key, capacityRange); end.Candidates.Add(candidate); } } }
private bool IsSameKey(RelationshipCandidate[] vector1, RelationshipCandidate[] vector2) { foreach (RelationshipGroupEnd end in this.endsWhichFormTheKey) { EntityDataKey key1 = vector1.Where(r => r.Parent == end).Select(r => r.EntityDataKey).Single(); EntityDataKey key2 = vector2.Where(r => r.Parent == end).Select(r => r.EntityDataKey).Single(); if (key1 != key2) { return(false); } } return(this.endsWhichFormTheKey.Count > 0); }
/// <summary> /// Sets the EntityDataKey for the specified association role. /// </summary> /// <param name="roleName">The association role name.</param> /// <param name="key">EntityDataKey for the association role.</param> public void SetRoleKey(string roleName, EntityDataKey key) { ExceptionUtilities.CheckArgumentNotNull(key, "key"); int ordinal = this.GetRoleNameOrdinal(roleName); List<string> expectedKeyNames = this.GetKeyNamesForRoleName(roleName).ToList(); if (expectedKeyNames.Count != key.KeyNames.Count || expectedKeyNames.Join(key.KeyNames, n1 => n1, n2 => n2, (n1, n2) => n1).Count() != expectedKeyNames.Count) { throw new TaupoArgumentException("Specified key does not match key metadata for the role '" + roleName + "'."); } this.data[ordinal] = key; }
private bool ResolveConstraintValue(EntitySetDataRow dependentRow, MemberProperty property, PropertyConstraint constraint, out object value) { value = null; List <AssociationSetDataRow> associationRows = this.data[constraint.AssociationSet].Rows.Where( r => ReferenceEquals(r.GetRoleKey(constraint.DependentRoleName), dependentRow.Key)).ToList(); if (associationRows.Count == 0) { return(false); } if (associationRows.Count > 1) { throw new TaupoInvalidOperationException(string.Format( CultureInfo.InvariantCulture, "Multiplicity constraint violated: the association set '{0}' has multiple rows with the same role key for the dependent role '{1}'.", constraint.AssociationSet.Name, constraint.DependentRoleName)); } EntityDataKey principalKey = associationRows[0].GetRoleKey(constraint.PrincipalRoleName); EntitySetDataRow principalRow = this.data[constraint.PrincipalEntitySet].Rows.Where(r => ReferenceEquals(r.Key, principalKey)).SingleOrDefault(); if (principalRow != null) { List <PropertyConstraint> constraints; if (this.TryGetConstraints(principalRow, constraint.PrincipalProperty, out constraints)) { var item = new KeyValuePair <EntitySetDataRow, MemberProperty>(dependentRow, property); this.visited.Add(item); value = this.ResolvePropertyValue(principalRow, constraint.PrincipalProperty, constraints); this.visited.Remove(item); } else { value = principalRow[constraint.PrincipalProperty.Name]; } } else if (constraint.PrincipalProperty.IsPrimaryKey) { value = principalKey[constraint.PrincipalProperty.Name]; } return(true); }
private EntityDataKey GetEntityKey(QueryStructuralValue entity) { ExceptionUtilities.CheckArgumentNotNull(entity, "entity"); return(EntityDataKey.CreateFromValues(entity.Type.Properties.Where(p => p.IsPrimaryKey).Select(p => new NamedValue(p.Name, entity.GetScalarValue(p.Name).Value)))); }
/// <summary> /// Initializes a new instance of the <see cref="EntityKey"/> class. /// </summary> /// <param name="entitySetName">The name of the entity set.</param> /// <param name="entityDataKey">The data key which contains key names and values.</param> public EntityKey(string entitySetName, EntityDataKey entityDataKey) { this.entitySetName = entitySetName; this.entityDataKey = entityDataKey; }
private EntityDataKey GetEntityKey(QueryStructuralType type, SerializableEntity entity) { ExceptionUtilities.CheckArgumentNotNull(type, "type"); ExceptionUtilities.CheckArgumentNotNull(entity, "entity"); return(EntityDataKey.CreateFromValues(entity.Properties.Where(p => type.Properties.Any(k => k.IsPrimaryKey && k.Name == p.Name)).Select(p => this.DataOracleConverter.Convert(p)))); }
internal EntitySetDataRowData(EntityDataKey key, string[] nonKeyPropertyPaths, string[] dynamicPropertyPaths, string fullEntityTypeName) { this.dynamicData = new Dictionary<string, object>(); this.dynamicPropertyPaths = dynamicPropertyPaths; this.nonKeyPropertyPaths = nonKeyPropertyPaths; this.key = key; this.fullEntityTypeName = fullEntityTypeName; // Initialize all the data for property non collection non key property paths to unitialized foreach (string propertyPath in this.nonKeyPropertyPaths) { this.dynamicData.Add(propertyPath, UninitializedData.Value); } }
/// <summary> /// Examines the required relationships from <paramref name="source"/> and then populates them in <paramref name="graph"/>. /// </summary> /// <param name="graph">The <see cref="List{IEntitySetData}"/> to which to add the new instance.</param> /// <param name="source">The entity from which to find required relationships and populate them.</param> /// <param name="sourceEntitySet">The <see cref="EntitySet"/> in which <paramref name="source"/> resides.</param> /// <param name="sourceEntityType">The <see cref="EntityType"/> of which the <paramref name="source"/> is an instance.</param> /// <param name="sourceKey">The <see cref="EntityDataKey"/> of the <paramref name="source"/> instance.</param> /// <param name="data"><see cref="EntityContainerData"/> that contains the structural data from which to create objects.</param> /// <param name="processedEntities">The entity instances which have been translated from structural data into objects.</param> /// <param name="processedAssociations">The association instances which have been translated from structural data into calls to <paramref name="connectEntities"/>.</param> /// <param name="entityCreated">A callback function invoked every time a new entity instance is created and its properties are initialized.</param> /// <param name="connectEntities">A callback used to connect two objects together. Examples of actions include setting navigation properties, /// synchronizing FKs to PK values, and/or using the IRelatedEnd or SetLink APIs. The first two parameters are the objects that need to /// be connected, and the third is the <see cref="RelationshipSide"/> describing the side of the relationship which the first object participates /// in.</param> private void CreateGraphCore( List <IEntitySetData> graph, IEntitySetData source, EntitySet sourceEntitySet, EntityType sourceEntityType, EntityDataKey sourceKey, EntityContainerData data, Dictionary <EntityKey, IEntitySetData> processedEntities, HashSet <AssociationInstance> processedAssociations, Action <IEntitySetData> entityCreated, ConnectEntitiesCallback connectEntities) { var requiredRelationships = from r in sourceEntitySet.Container.RelationshipTypes() let side = r.Sides.FirstOrDefault(e => sourceEntityType.IsKindOf(e.FromEntityType) && sourceEntitySet == e.FromEntitySet && e.ToMultiplicity == EndMultiplicity.One) where side != null select new { Relationship = r, SourceSide = side }; foreach (var r in requiredRelationships) { var relationship = r.Relationship; var sourceSide = r.SourceSide; var associationRow = data.GetAssociationSetData(relationship.AssociationSet.Name).Rows .Single(row => row.GetRoleKey(sourceSide.FromRoleName).Equals(sourceKey)); var targetKey = associationRow.GetRoleKey(sourceSide.ToRoleName); var targetEntitySet = sourceSide.ToEntitySet; var targetEntityKey = new EntityKey(targetEntitySet.ContainerQualifiedName, targetKey); IEntitySetData targetEntity; if (!processedEntities.TryGetValue(targetEntityKey, out targetEntity)) { var targetRow = data.GetEntitySetData(targetEntitySet.Name).Rows.Single(row => row.Key.Equals(targetKey)); targetEntity = this.CreateObjectFromRow(targetRow); if (entityCreated != null) { entityCreated(targetEntity); } graph.Add(targetEntity); processedEntities.Add(targetEntityKey, targetEntity); InvokeConnectEntitiesCallback(source, targetEntity, relationship, sourceSide, processedAssociations, connectEntities); this.CreateGraphCore( graph, targetEntity, targetEntitySet, targetRow.EntityType, targetKey, data, processedEntities, processedAssociations, entityCreated, connectEntities); } else { InvokeConnectEntitiesCallback(source, targetEntity, relationship, sourceSide, processedAssociations, connectEntities); } } }