예제 #1
0
        private void PopulateNavigateResult(EntitySetDataRow row, QueryEntityValue entityInstance, AssociationSet associationSet, AssociationSetEnd fromSetEnd, AssociationSetEnd toSetEnd)
        {
            EntityContainerData containerData = row.Parent.Parent;
            var associationSetData            = containerData.GetAssociationSetData(associationSet.Name);

            var targetInstanceLookup = this.rowInstances[toSetEnd.EntitySet.Name];

            var associatedObjects = associationSetData.Rows
                                    .Where(r => r.GetRoleKey(fromSetEnd.AssociationEnd.RoleName).Equals(row.Key))
                                    .Select(r => targetInstanceLookup[r.GetRoleKey(toSetEnd.AssociationEnd.RoleName)])
                                    .ToArray();

            var toEntityType      = toSetEnd.AssociationEnd.EntityType;
            var toQueryEntityType = this.GetQueryType(toSetEnd.EntitySet.Name, toEntityType);

            if (toSetEnd.AssociationEnd.Multiplicity == EndMultiplicity.Many)
            {
                var collectionType  = toQueryEntityType.CreateCollectionType();
                var collectionValue = collectionType.CreateCollectionWithValues(associatedObjects);
                entityInstance.SetNavigateResult(associationSet.AssociationType, toSetEnd.AssociationEnd, collectionValue);
            }
            else
            {
                if (associatedObjects.Length == 0)
                {
                    entityInstance.SetNavigateResult(associationSet.AssociationType, toSetEnd.AssociationEnd, toQueryEntityType.NullValue);
                }
                else
                {
                    if (associatedObjects.Length != 1)
                    {
                        var debugAssociatedValues = string.Join("," + Environment.NewLine, associatedObjects.Select(ao => ao.ToString()));
                        throw new TaupoInfrastructureException(
                                  string.Format(
                                      CultureInfo.InvariantCulture,
                                      "Found {0} associated objects for {1}.{2}, on Entity Instance {3} associated Objects = {4}",
                                      associatedObjects.Length,
                                      associationSet.AssociationType.FullName,
                                      fromSetEnd.AssociationEnd.RoleName,
                                      entityInstance,
                                      debugAssociatedValues));
                    }

                    var targetInstance = associatedObjects.Single();
                    entityInstance.SetNavigateResult(associationSet.AssociationType, toSetEnd.AssociationEnd, targetInstance);
                }
            }
        }
예제 #2
0
        /// <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);
                }
            }
        }