Esempio n. 1
0
        /// <summary>
        /// Extends value population to include stream data
        /// </summary>
        /// <param name="row">The row containing the data</param>
        /// <param name="instance">The structural instacne</param>
        protected override void PopulateInstanceFromRow(EntitySetDataRow row, QueryStructuralValue instance)
        {
            base.PopulateInstanceFromRow(row, instance);
            var rowWithStreams = row as EntitySetDataRowWithStreams;

            if (rowWithStreams != null)
            {
                foreach (var stream in rowWithStreams.Streams)
                {
                    if (stream.IsEditLinkBasedOnConvention)
                    {
                        ExceptionUtilities.CheckObjectNotNull(this.LinkGenerator, "Cannot compute convention-based edit link without injected generator");
                        stream.EditLink = this.LinkGenerator.GenerateStreamEditLink(instance, stream.Name);

                        // for the default stream, there must always be a self-link
                        if (stream.Name == null && stream.SelfLink == null)
                        {
                            stream.SelfLink = stream.EditLink;
                        }
                    }

                    instance.SetStreamValue(stream.Name, stream.ContentType, stream.ETag, stream.EditLink, stream.SelfLink, stream.Content);
                }
            }

            instance.MarkDynamicPropertyValues();
        }
        private void PopulateNavigations(EntitySetDataRow row, QueryStructuralValue instance)
        {
            var                 entityInstance = instance as QueryEntityValue;
            EntitySetData       entitySetData  = row.Parent;
            EntityContainerData containerData  = entitySetData.Parent;

            foreach (AssociationSet associationSet in containerData.EntityContainer.AssociationSets)
            {
                foreach (var fromSetEnd in associationSet.Ends.Where(e => e.EntitySet == entitySetData.EntitySet))
                {
                    var fromEntityType = fromSetEnd.AssociationEnd.EntityType;
                    if (!row.EntityType.IsKindOf(fromEntityType))
                    {
                        continue;
                    }

                    var toSetEnd = associationSet.GetOtherEnd(fromSetEnd);

                    this.PopulateNavigateResult(row, entityInstance, associationSet, fromSetEnd, toSetEnd);

                    // if Navigation property exists, populate it as well
                    var navProp = row.EntityType.AllNavigationProperties.SingleOrDefault(p => p.Association == associationSet.AssociationType &&
                                                                                         p.ToAssociationEnd == toSetEnd.AssociationEnd);
                    if (navProp != null)
                    {
                        instance.SetValue(navProp.Name, entityInstance.GetNavigateResult(navProp.Association, navProp.ToAssociationEnd));
                    }
                }
            }
        }
 private void ConsiderCandidateForRelationships(EntitySetDataRow row)
 {
     foreach (RelationshipSelector rs in this.relationshipSelectors)
     {
         rs.ConsiderCandidate(row.Parent.EntitySet, row.EntityType, row.Key);
     }
 }
        private void CreateRelationships(
            EntityContainerData data,
            ref int createdEntitiesCount,
            ref int createdAssociationsCount)
        {
            List <RelationshipDescription> relationshipsToCreate;
            List <KeyValuePair <EntitySet, EntityType> > entitiesToCreateInCurrentBatch;
            int loopCount = 0;

            while (this.GetRelationshipsAndEntitiesToCreate(out relationshipsToCreate, out entitiesToCreateInCurrentBatch))
            {
                loopCount++;

                // there are times when relationships are unable to be created for particular entity type graphs
                // in these situations this check guards against running infinitely long, adding 20
                // ensures that all models get at least 100 loops to generate relationship data, otherwise this
                // guard might be too low
                if (loopCount > ((this.relationshipSelectors.Count * 4) + 20))
                {
                    throw new TaupoInvalidOperationException("Specified relationship requirements cannot be met. Make sure capacity selectors don't contradict each other.");
                }

                this.PopulateAssociationSetRows(data, relationshipsToCreate);
                createdAssociationsCount += relationshipsToCreate.Count;

                foreach (var setTypePair in entitiesToCreateInCurrentBatch)
                {
                    EntitySetDataRow r = this.PopulateNewEntitySetRow(data, setTypePair.Key, setTypePair.Value);
                    createdEntitiesCount++;
                    this.ConsiderCandidateForRelationships(r);
                }
            }
        }
            private void ResolveConstraints(EntitySetDataRow row, PropertyWithConstraints propertyWithConstraints)
            {
                List <PropertyConstraint> constraints = propertyWithConstraints.GetConstraints(row.EntityType);

                if (constraints.Count > 0)
                {
                    this.ResolvePropertyValue(row, propertyWithConstraints.Property, constraints);
                }
            }
Esempio n. 6
0
        private IEntitySetData CreateObjectFromRow(EntitySetDataRow targetRow)
        {
            var targetEntityType = targetRow.EntityType;

            var targetObject = this.ObjectServices.GetObjectAdapter(targetEntityType.FullName).CreateData(
                targetRow.PropertyPaths.Select(p => new NamedValue(p, targetRow.GetValue(p))).Where(v => v.Value != UninitializedData.Value));

            return(this.CreateEntitySetObjectData(targetObject, targetRow.Parent.EntitySet.ContainerQualifiedName));
        }
            private object ResolvePropertyValue(EntitySetDataRow row, MemberProperty property, List <PropertyConstraint> constraints)
            {
                if (this.resolved.Any(kv => kv.Key == row && kv.Value == property))
                {
                    return(row[property.Name]);
                }

                KeyValuePair <EntitySetDataRow, MemberProperty> sameItem = this.visited.Where(kv => kv.Key == row && kv.Value == property).SingleOrDefault();

                if (sameItem.Key != null)
                {
                    int           indexCycleStartsWith = this.visited.IndexOf(sameItem);
                    List <object> values = this.visited.Where((kv, i) => i >= indexCycleStartsWith).Select(kv => kv.Key[kv.Value.Name]).Distinct(ValueComparer.Instance).ToList();
                    if (values.Count > 1)
                    {
                        throw new TaupoInvalidOperationException("Referential constraint cycle detected: " + GetReferentialConstraintCycleDescription(this.visited, indexCycleStartsWith));
                    }

                    return(values[0]);
                }

                var candidates = new List <object>();

                foreach (PropertyConstraint constraint in constraints)
                {
                    object candidate;
                    if (this.ResolveConstraintValue(row, property, constraint, out candidate))
                    {
                        candidates.Add(candidate);
                    }
                }

                if (candidates.Distinct(ValueComparer.Instance).Count() > 1)
                {
                    throw new TaupoInvalidOperationException("Overlapping foreign keys with conflicting values detected: " + GetOverlappingForeignKeyDescription(constraints));
                }

                object value;

                if (candidates.Count > 0)
                {
                    value = candidates[0];
                    if (!ValueComparer.Instance.Equals(value, row[property.Name]))
                    {
                        row[property.Name] = value;
                    }
                }
                else
                {
                    value = row[property.Name];
                }

                this.resolved.Add(new KeyValuePair <EntitySetDataRow, MemberProperty>(row, property));

                return(value);
            }
        private EntitySetDataRow PopulateEntitySetRow(EntityContainerData data, EntitySet entitySet, EntityType entityType, IEnumerable <NamedValue> entityData)
        {
            EntitySetDataRow row = data[entitySet].AddNewRowOfType(entityType);

            foreach (NamedValue namedValue in entityData)
            {
                row.SetValue(namedValue.Name, namedValue.Value);
            }

            this.entitySetAndTypeSelector.IncrementCount(entitySet, entityType);

            return(row);
        }
        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);
                }
            }
        }
            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);
            }
        /// <summary>
        /// Tries to get next data to upload.
        /// </summary>
        /// <param name="data">The data to upload.</param>
        /// <returns>True if there is a data for upload, false otherwise.</returns>
        public virtual bool TryPopulateNextData(out EntityContainerData data)
        {
            ExceptionUtilities.CheckObjectNotNull(this.StructuralDataServices, "StructuralGenerators cannot be null.");

            this.CreateEntitySetAndTypeSelectorIfNull();
            this.CreateRelationshipSelectorsIfNull();

            if (this.seedData != null)
            {
                data          = this.seedData;
                this.seedData = null;
            }
            else
            {
                data = new EntityContainerData(this.EntityContainer);
            }

            int createdEntitiesCount = 0, createdAssociationsCount = 0;

            this.CreateRelationships(data, ref createdEntitiesCount, ref createdAssociationsCount);

            EntitySet  entitySet;
            EntityType entityType;

            while (this.GetNextEntitySetAndTypeToCreate(out entitySet, out entityType))
            {
                EntitySetDataRow row = this.PopulateNewEntitySetRow(data, entitySet, entityType);
                createdEntitiesCount++;
                this.ConsiderCandidateForRelationships(row);

                this.CreateRelationships(data, ref createdEntitiesCount, ref createdAssociationsCount);

                if (createdEntitiesCount >= this.ThresholdForNumberOfEntities && this.ThresholdForNumberOfEntities != -1)
                {
                    break;
                }
            }

            if (this.ReferentialConstraintsResolver != null)
            {
                this.ReferentialConstraintsResolver.ResolveReferentialConstraints(data);
            }

            return(createdEntitiesCount > 0 || createdAssociationsCount > 0);
        }
Esempio n. 12
0
        private void PopulateScalarAndComplexCollectionAndNonCollectionProperties(EntitySetDataRow row, QueryStructuralValue instance)
        {
            IEnumerable <QueryProperty> allProperties = instance.Type.Properties;

            if (instance.Type is QueryEntityType)
            {
                List <string> properties = ((QueryEntityType)instance.Type).EntityType.AllProperties.Select(p => p.Name).ToList();
                allProperties = instance.Type.Properties.Where(m => properties.Contains(m.Name));
            }

            List <QueryProperty> nonEntityQueryProperties = new List <QueryProperty>();

            foreach (QueryProperty qp in allProperties)
            {
                nonEntityQueryProperties.Add(qp);
            }

            this.BuildStructuralPropertiesQueryValue(instance, string.Empty, row.EntityType.AllProperties.ToList(), nonEntityQueryProperties, row);
        }
            private bool TryGetConstraints(EntitySetDataRow row, MemberProperty property, out List <PropertyConstraint> constraints)
            {
                constraints = null;

                List <PropertyWithConstraints> propertiesWithConstraints;

                if (this.entitySetToConstraintsMap.TryGetValue(row.Parent.EntitySet, out propertiesWithConstraints))
                {
                    constraints = propertiesWithConstraints
                                  .Where(p => p.Property == property)
                                  .Select(p => p.GetConstraints(row.EntityType)).SingleOrDefault();

                    if (constraints != null && constraints.Count == 0)
                    {
                        constraints = null;
                    }
                }

                return(constraints != null);
            }
Esempio n. 14
0
        private void BuildStructuralPropertiesQueryValue(QueryStructuralValue instance, string propertyPath, IList <MemberProperty> properties, IList <QueryProperty> queryProperties, EntitySetDataRow row)
        {
            ExceptionUtilities.Assert(properties.Count == queryProperties.Count, "QueryProperties '{0}' and MemberProperties '{1}' are not the same number!", CreateQueryPropertyList(queryProperties), CreateMemberPropertyList(properties));

            // TODO: Some Taupo framework pieces skip over StreamDataType properties
            foreach (MemberProperty childProperty in properties.Where(p => !(p.PropertyType is StreamDataType)))
            {
                string childPropertyPath = propertyPath + childProperty.Name;
                List <QueryProperty> childQueryProperties = queryProperties.Where(p => p.Name == childProperty.Name).ToList();
                ExceptionUtilities.Assert(childQueryProperties.Count == 1, "Could not find query property based on MemberProperty Name '{0}' in list of query properties '{1}'", childProperty.Name, CreateQueryPropertyList(childQueryProperties));

                QueryProperty childQueryProperty = childQueryProperties.First();

                QueryCollectionType childCollectionDataType = childQueryProperty.PropertyType as QueryCollectionType;
                QueryScalarType     childScalarType         = childQueryProperty.PropertyType as QueryScalarType;
                QueryComplexType    childComplexType        = childQueryProperty.PropertyType as QueryComplexType;

                if (childCollectionDataType != null)
                {
                    instance.SetValue(childProperty.Name, this.BuildCollectionQueryValue(childPropertyPath + ".", childCollectionDataType, row));
                }
                else if (childScalarType != null)
                {
                    var value      = row[childPropertyPath];
                    var queryValue = childScalarType.CreateValue(value);
                    instance.SetValue(childQueryProperty.Name, queryValue);
                }
                else
                {
                    ExceptionUtilities.CheckObjectNotNull(childComplexType, "Unknown type '{0}'", childProperty.PropertyType);

                    // If a complex type instance is null in the datarow, we will create a QueryStructuralValue indicating null and set it on the instance.
                    if (row.PropertyPaths.Contains(childPropertyPath) && row[childPropertyPath] == null)
                    {
                        instance.SetValue(childProperty.Name, new QueryStructuralValue(childComplexType, true, null, childComplexType.EvaluationStrategy));
                    }
                    else
                    {
                        QueryStructuralValue childInstance = childComplexType.CreateNewInstance();
                        this.BuildStructuralPropertiesQueryValue(childInstance, childPropertyPath + ".", childComplexType.ComplexType.Properties, childComplexType.Properties, row);
                        instance.SetValue(childProperty.Name, childInstance);
                    }
                }
            }
        }
Esempio n. 15
0
        private QueryValue BuildCollectionQueryValue(string propertyPath, QueryCollectionType queryCollectionType, EntitySetDataRow row)
        {
            QueryScalarType   scalarElementDataType      = queryCollectionType.ElementType as QueryScalarType;
            QueryComplexType  complexTypeElementDataType = queryCollectionType.ElementType as QueryComplexType;
            List <QueryValue> queryValues = new List <QueryValue>();

            if (scalarElementDataType != null)
            {
                int i = 0;
                while (row.PropertyPaths.Any(pp => pp == propertyPath + i))
                {
                    var value = row[propertyPath + i];
                    queryValues.Add(scalarElementDataType.CreateValue(value));
                    i++;
                }
            }
            else
            {
                ExceptionUtilities.CheckObjectNotNull(complexTypeElementDataType, "PropertyPath '{0}' is an invalid type '{1}'", propertyPath, queryCollectionType.ElementType);

                int i = 0;
                while (row.PropertyPaths.Where(pp => pp.StartsWith(propertyPath + i, StringComparison.Ordinal)).Count() > 0)
                {
                    QueryStructuralValue complexChildInstance = complexTypeElementDataType.CreateNewInstance();
                    this.BuildStructuralPropertiesQueryValue(complexChildInstance, propertyPath + i + ".", complexTypeElementDataType.ComplexType.Properties, complexTypeElementDataType.Properties, row);
                    queryValues.Add(complexChildInstance);
                    i++;
                }
            }

            return(queryCollectionType.CreateCollectionWithValues(queryValues.ToArray()));
        }
Esempio n. 16
0
 /// <summary>
 /// Helper method for populating property values on the given instance
 /// </summary>
 /// <param name="row">The row containing the data</param>
 /// <param name="instance">The structural instacne</param>
 protected virtual void PopulateInstanceFromRow(EntitySetDataRow row, QueryStructuralValue instance)
 {
     this.PopulateNavigations(row, instance);
     this.PopulateScalarAndComplexCollectionAndNonCollectionProperties(row, instance);
 }