/// <summary>
        /// Fills in the given type declaration based on the given metadata
        /// </summary>
        /// <param name="entityType">The entity type's metadata</param>
        /// <param name="entityTypeClass">The type declaration</param>
        protected override void DeclareEntityType(EntityType entityType, CodeTypeDeclaration entityTypeClass)
        {
            entityTypeClass.IsPartial = true;
            entityTypeClass.IsClass = true;

            if (entityType.IsAbstract)
            {
                entityTypeClass.SetAbstract();
            }

            if (entityType.BaseType != null)
            {
                entityTypeClass.BaseTypes.Add(entityType.BaseType.FullName);
            }

            // Add public constructor for this type
            var constructor = entityTypeClass.AddConstructor();

            // Declare all members that are declared
            foreach (MemberProperty memberProperty in entityType.Properties)
            {
                this.DeclareMemberProperty(memberProperty, entityTypeClass);
                this.DeclareOptionalPropertyInitializer(memberProperty, constructor);
            }

            // Declare all members that are declared
            foreach (NavigationProperty navigationProperty in entityType.NavigationProperties)
            {
                this.DeclareNavigationProperty(navigationProperty, entityTypeClass);
                this.DeclareOptionalPropertyInitializer(navigationProperty, constructor);
            }

            this.GenerateAttributes(entityType, entityTypeClass);
        }
Пример #2
0
 /// <summary>
 /// Adds new <see cref="EntityType"/> to the model.
 /// </summary>
 /// <param name="entityType">Entity type to be added.</param>
 public void Add(EntityType entityType)
 {
     ExceptionUtilities.CheckArgumentNotNull(entityType, "entityType");
     ExceptionUtilities.Assert(entityType.Model == null, "Entity type was already added to another model");
     entityType.Model = this;
     this.entityTypesList.Add(entityType);
 }
        /// <summary>
        /// Generates and adds stream related attributes and elements to the entity type
        /// </summary>
        /// <param name="entityType">The entity type's metadata</param>
        /// <param name="entityTypeClass">The entity types declaration</param>
        protected override void GenerateHasStreamEntityTypeCodeElements(EntityType entityType, CodeTypeDeclaration entityTypeClass)
        {
            ExceptionUtilities.Assert(entityType.HasStream(), "This method should not be called for entity types without stream.");
            
            ClientMediaEntryAnnotation clientMediaEntryAnnotation = entityType.Annotations.OfType<ClientMediaEntryAnnotation>().FirstOrDefault();
            if (clientMediaEntryAnnotation != null)
            {
                // generate MediaEntry and MimeTypeProperty properties and attributes for V1 style stream support
                var attributeArguments1 = new CodeAttributeArgument[]
                {
                    new CodeAttributeArgument(Code.Primitive(clientMediaEntryAnnotation.MediaEntryName)),
                };
                var attributeArguments2 = new CodeAttributeArgument[]
                {
                    new CodeAttributeArgument(Code.Primitive(clientMediaEntryAnnotation.MediaEntryName)),
                    new CodeAttributeArgument(Code.Primitive(clientMediaEntryAnnotation.MimeTypePropertyName))
                };

                entityTypeClass.AddCustomAttribute(Code.TypeRef("MediaEntry"), attributeArguments1);
                entityTypeClass.AddCustomAttribute(Code.TypeRef("MimeTypeProperty"), attributeArguments2);
                entityTypeClass.AddAutoImplementedProperty(Code.TypeRef<byte[]>(), clientMediaEntryAnnotation.MediaEntryName);
                entityTypeClass.AddAutoImplementedProperty(Code.TypeRef<string>(), clientMediaEntryAnnotation.MimeTypePropertyName);
            }
            else
            {
                // No ClientMediaEntryAnnotation is found, generate HasStream atttribute for V2 and up stream support
                entityTypeClass.AddCustomAttribute(Code.TypeRef("HasStream"));
            }
        }
        /// <summary>
        /// Generates the conventional stream edit link for the given entity: http://serviceRoot/SetName(keyValues)/$value
        /// </summary>
        /// <param name="entitySet">The entity set of the entity</param>
        /// <param name="entityType">The type of the entity</param>
        /// <param name="keyValues">They values of the entity's key</param>
        /// <returns>The convention-based stream edit link</returns>
        public string GenerateDefaultStreamEditLink(EntitySet entitySet, EntityType entityType, IEnumerable<NamedValue> keyValues)
        {
            // null checks performed by this helper
            var uri = this.GenerateEntityEditLinkUri(entitySet, entityType, keyValues);

            uri.Segments.Add(SystemSegment.Value);

            return this.UriToStringConverter.ConvertToString(uri);
        }
 private void RemoveObjectLayerOnlyNavigationProperties(EntityType entityType)
 {
     for (int i = entityType.NavigationProperties.Count - 1; i >= 0; i--)
     {
         if (entityType.NavigationProperties[i].Annotations.OfType<ObjectLayerOnlyAnnotation>().Any())
         {
             entityType.NavigationProperties.RemoveAt(i);
         }
     }
 }
        /// <summary>
        /// Gets the properties values for all scalar and complex properties in the form of <see cref="NamedValue"/>.
        /// </summary>
        /// <param name="objectServices">The object services.</param>
        /// <param name="entity">The entity.</param>
        /// <param name="entityType">Type of the entity.</param>
        /// <returns>The properties values.</returns>
        public static IList<NamedValue> GetPropertiesValues(this IEntityModelObjectServices objectServices, object entity, EntityType entityType)
        {
            ExceptionUtilities.CheckArgumentNotNull(objectServices, "objectServices");
            ExceptionUtilities.CheckArgumentNotNull(entity, "entity");
            ExceptionUtilities.CheckArgumentNotNull(entityType, "entityType");

            List<NamedValue> result = new List<NamedValue>();
            CachePropertiesValues(result, string.Empty, entityType.FullName, entityType.AllProperties, entity, objectServices);
            return result;
        }
        /// <summary>
        /// Fills in the given type declaration based on the given metadata and implements INotifyPropertyChanged on the type
        /// </summary>
        /// <param name="entityType">The entity type's metadata</param>
        /// <param name="entityTypeClass">The type declaration</param>
        protected override void DeclareEntityType(EntityType entityType, CodeTypeDeclaration entityTypeClass)
        {
            base.DeclareEntityType(entityType, entityTypeClass);

            // if an entity type is a derived type, the base type should have implemented INotifyPropertyChanged
            if (entityType.BaseType == null)
            {
                this.ImplementINotifyPropertyChanged(entityTypeClass);
            }
        }
        private int GetNumberOfInheritanceLevel(EntityModelSchema model, EntityType entityType)
        {
            var children = model.EntityTypes.Where(e => e.BaseType == entityType);

            if (children.Any())
            {
                return 1 + children.Max(e => this.GetNumberOfInheritanceLevel(model, e));
            }

            return 0;
        }
        /// <summary>
        /// Improve the model if goals not yet met
        /// </summary>
        /// <param name="model">model to improve</param>
        public override void Improve(EntityModelSchema model)
        {
            var roots = this.GetInheritanceRoots(model);

            int numberOfRootsToAdd = this.MinNumberOfInheritanceRoots - roots.Count();
            for (int i = 0; i < numberOfRootsToAdd; i++)
            {
                var root = new EntityType();
                model.Add(root);
                model.Add(new EntityType() { BaseType = root });
            }
        }
        /// <summary>
        /// Improve the model if goals not yet met
        /// </summary>
        /// <param name="model">model to improve</param>
        public override void Improve(EntityModelSchema model)
        {
            var baseType = new EntityType();
            model.Add(baseType);

            for (int i = 0; i < this.MinNumberOfInheritanceLevels; i++)
            {
                var derivedType = new EntityType() { BaseType = baseType };
                model.Add(derivedType);

                baseType = derivedType;
            }        
        }
Пример #11
0
        /// <summary>
        /// Visits an entity
        /// </summary>
        /// <param name="entity">entity to visit</param>
        protected virtual void VisitEntityType(EntityType entity)
        {
            this.VisitAnnotatedItem(entity);

            foreach (var property in entity.Properties)
            {
                this.VisitMemberProperty(property);
            }

            foreach (var navigationProperty in entity.NavigationProperties)
            {
                this.VisitNavigationProperty(navigationProperty);
            }
        }
Пример #12
0
        /// <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);
                }
            }
        }
        /// <summary>
        /// Improve the model if goals not yet met
        /// </summary>
        /// <param name="model">model to improve</param>
        public override void Improve(EntityModelSchema model)
        {
            var baseTypes = model.EntityTypes.Where(e => model.EntityTypes.Any(d => d.BaseType == e)).ToList();

            foreach (var baseType in baseTypes)
            {
                int numberOfSiblingsToAdd = this.MinNumberOfInheritanceSiblings - model.EntityTypes.Count(d => d.BaseType == baseType);

                for (int i = 0; i < numberOfSiblingsToAdd; i++)
                {
                    var derivedType = new EntityType() { BaseType = baseType };
                    model.Add(derivedType);
                }
            }
        }
        /// <summary>
        /// Creates a default instance of a CLR object which represents the specified <paramref name="entityType"/> and <paramref name="entitySet"/>.
        /// </summary>
        /// <param name="objectServices">The object services.</param>
        /// <param name="entitySet">The <see cref="EntitySet"/> in which the <paramref name="entityType"/> resides.</param>
        /// <param name="entityType">The <see cref="EntityType"/> from which to create a CLR object.</param>
        /// <returns>A CLR object that maps to the <paramref name="entityType"/>.</returns>
        public static object CreateData(this IEntityModelObjectServices objectServices, EntitySet entitySet, EntityType entityType)
        {
            ExceptionUtilities.CheckArgumentNotNull(objectServices, "objectServices");
            ExceptionUtilities.CheckArgumentNotNull(entitySet, "entitySet");
            ExceptionUtilities.CheckArgumentNotNull(entityType, "entityType");

            if (entityType.IsAbstract)
            {
                throw new TaupoArgumentException("Cannot create data for abstract entity type.");
            }

            var generator = objectServices.GetEntitySetObjectGenerator(entityType.FullName, entitySet.ContainerQualifiedName);
            var entity = generator.GenerateData().Data;
            return entity;
        }
        /// <summary>
        /// Checks for a name collision between an action's name and a property's name
        /// </summary>
        /// <param name="function">The function to check for name property collision</param>
        /// <param name="bindingEntityDataType">The bindingEntityDataType is the entity to check against</param>
        /// <param name="actualInstanceEntityType">the entity type of the instance of the entity</param>
        /// <returns>a string representing the entity container's name</returns>
        public string BuildExpectedContainerName(Function function, EntityDataType bindingEntityDataType, EntityType actualInstanceEntityType)
        {
            string containerName = string.Empty;

            // check for open entity type on the function definition or on the actual entity itself
            if (bindingEntityDataType.Definition.IsOpen || actualInstanceEntityType.IsOpen)
            {
                containerName = string.Concat(function.Model.GetDefaultEntityContainer().Name, ".");
            }

            var foundNameCollision = bindingEntityDataType.Definition.AllProperties.Where(a => a.Name.Equals(function.Name)).FirstOrDefault();
            if (foundNameCollision != null && !bindingEntityDataType.Definition.IsOpen)
            {
                containerName = string.Concat(function.Model.GetDefaultEntityContainer().Name, ".");
            }

            return containerName;
        }
Пример #16
0
        /// <summary>
        /// Constructs an entity with the given property values
        /// </summary>
        /// <param name="entityType">The metadata for the entity type</param>
        /// <param name="namedValues">The property values. Keys are expected to be '.' delimited property paths.</param>
        /// <returns>An entity instance with the given values</returns>
        public EntityInstance EntityInstance(EntityType entityType, IEnumerable<NamedValue> namedValues)
        {
            ExceptionUtilities.CheckArgumentNotNull(entityType, "entityType");

            EntityInstance instance = new EntityInstance(entityType.FullName, namedValues == null);

            if (entityType.GetBaseTypesAndSelf().Any(t => t.HasStream()))
            {
                instance.AsMediaLinkEntry();
            }

            if (namedValues != null)
            {
                this.PopulatePropertiesFromPaths(instance, entityType.AllProperties, null, namedValues);

                // TODO: populate navigation properties
            }

            return instance;
        }
Пример #17
0
        /// <summary>
        /// Builds an entity instance of the given type out of the given anonymous object
        /// </summary>
        /// <param name="entityType">The metadata type information for the entity</param>
        /// <param name="anonymous">The data as an anonymous type</param>
        /// <returns>An entity instance with the given values</returns>
        public EntityInstance EntityInstance(EntityType entityType, object anonymous)
        {
            ExceptionUtilities.CheckArgumentNotNull(entityType, "entityType");

            EntityInstance instance = new EntityInstance(entityType.FullName, anonymous == null);

            if (entityType.GetBaseTypesAndSelf().Any(t => t.HasStream()))
            {
                instance.AsMediaLinkEntry();
            }

            // TODO: id?
            if (anonymous != null)
            {
                this.PopulatePropertiesFromObject(instance, entityType.AllProperties, anonymous);

                // TODO: populate navigation properties
            }

            return instance;
        }
Пример #18
0
        /// <summary>
        /// Constructs a key expression segment with the given values
        /// </summary>
        /// <param name="type">The type for the key</param>
        /// <param name="values">The values for the key</param>
        /// <returns>A key expression segment</returns>
        public static ODataUriSegment Key(EntityType type, IEnumerable<NamedValue> values)
        {
            ExceptionUtilities.CheckArgumentNotNull(type, "type");
            ExceptionUtilities.CheckCollectionNotEmpty(values, "values");

            // intentionally avoiding using a linq-to-objects query as it introduces a compiler-generated class that shows up in the dependency layering output
            List<KeyValuePair<MemberProperty, object>> pairs = new List<KeyValuePair<MemberProperty, object>>();
            Dictionary<string, MemberProperty> keyProperties = new Dictionary<string, MemberProperty>();
            foreach (var keyProperty in type.AllKeyProperties)
            {
                keyProperties[keyProperty.Name] = keyProperty;
            }

            foreach (var pair in values)
            {
                MemberProperty keyProperty;
                ExceptionUtilities.Assert(keyProperties.TryGetValue(pair.Name, out keyProperty), "Could not find key property '" + pair.Name + "'");
                pairs.Add(new KeyValuePair<MemberProperty, object>(keyProperty, pair.Value));
            }

            ExceptionUtilities.Assert(pairs.Count == values.Count(), "Number of pairs does not match input");
   
            return new KeyExpressionSegment(pairs);
        }
        internal static bool TryGetExpectedType(ODataRequest request, out EntityType entityType)
        {
            EntitySet entitySet;
            if (request.Uri.TryGetExpectedEntitySet(out entitySet))
            {
                var possibleTypes = entitySet.Container.Model.EntityTypes.Where(t => t.IsKindOf(entitySet.EntityType)).ToList();
                if (possibleTypes.Count == 1)
                {
                    entityType = possibleTypes[0];
                    return true;
                }

                string typeName = null;
                if (entitySet.EntityType.HasStream())
                {
                    typeName = request.GetHeaderValueIfExists(HttpHeaders.MediaLinkEntryEntityTypeHint);
                }
                else if (request.Body != null && request.Body.RootElement.ElementType == ODataPayloadElementType.EntityInstance)
                {
                    typeName = ((EntityInstance)request.Body.RootElement).FullTypeName;
                }

                if (typeName != null)
                {
                    entityType = possibleTypes.SingleOrDefault(t => t.FullName == typeName);
                    return entityType != null;
                }
            }

            entityType = null;
            return false;
        }
 /// <summary>
 /// Initializes a new instance of the EntitySetDataRowWithStreams class
 /// </summary>
 /// <param name="parent">The parent of the row</param>
 /// <param name="entityType">The entity type of the row</param>
 public EntitySetDataRowWithStreams(EntitySetData parent, EntityType entityType)
     : base(parent, entityType)
 {
     this.Streams = new List<StreamData>();
 }
 /// <summary>
 /// Gets the CLR instance type for the specified entity type.
 /// </summary>
 /// <param name="entity">The entity type to get the instance type for.</param>
 /// <param name="canReflectOnInstanceType">true if reflection over the instance type is allowed; otherwise false.</param>
 /// <returns>The CLR instance type to use.</returns>
 protected override Type GetEntityInstanceType(EntityType entity, out bool canReflectOnInstanceType)
 {
     canReflectOnInstanceType = false;
     return typeof(DSPResource);
 }
        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 EntitySetDataRow PopulateNewEntitySetRow(EntityContainerData data, EntitySet entitySet, EntityType entityType)
        {
            var entityData = this.StructuralDataServices.GetStructuralGenerator(entityType.FullName, this.EntityContainer.Name + "." + entitySet.Name).GenerateData();

            return this.PopulateEntitySetRow(data, entitySet, entityType, entityData);
        }
        private bool GetNextEntitySetAndTypeToCreate(out EntitySet entitySet, out EntityType entityType)
        {
            if (this.entitiesToCreateInNextBatch.Count > 0)
            {
                var entitySetAndType = this.Random.ChooseFrom(this.entitiesToCreateInNextBatch);
                entitySet = entitySetAndType.Key;
                entityType = entitySetAndType.Value;

                return true;
            }
            else
            {
                return this.entitySetAndTypeSelector.TryGetNextEntitySetAndTypeToCreate(out entitySet, out entityType);
            }
        }
        /// <summary>
        /// Sets the minimum number of entities to be created for the specified entity set and type.
        /// </summary>
        /// <param name="entitySet">The entity set.</param>
        /// <param name="entityType">The entity type.</param>
        /// <param name="count">The minimum number of entities to create.</param>
        public void SetMinimumNumberOfEntities(EntitySet entitySet, EntityType entityType, int count)
        {
            ExceptionUtilities.CheckArgumentNotNull(entitySet, "entitySet");
            ExceptionUtilities.CheckArgumentNotNull(entityType, "entityType");

            this.SetMinimumNumberOfEntities(entitySet.Name, entityType.Name,  count);
        }
        /// <summary>
        /// Adds seed data to the <see cref="EntityContainerData"/> created by this instance by
        /// calling <see cref="TryPopulateNextData"/>.
        /// </summary>
        /// <param name="entitySet">The <see cref="EntitySet"/> to which the new seed instance belongs.</param>
        /// <param name="entityType">The <see cref="EntityType"/> of the new seed instance.</param>
        /// <param name="entityData">A collection of <see cref="NamedValue"/>s that describe the structural data of the instance.</param>
        /// <returns>The <see cref="EntityDataKey"/> that describes the seed instance.</returns>
        public EntityDataKey Seed(EntitySet entitySet, EntityType entityType, IEnumerable<NamedValue> entityData)
        {
            this.CreateEntitySetAndTypeSelectorIfNull();
            this.CreateRelationshipSelectorsIfNull();

            if (this.seedData == null)
            {
                this.seedData = new EntityContainerData(this.entityContainer);
            }

            var seedRow = this.PopulateEntitySetRow(this.seedData, entitySet, entityType, entityData);
            this.ConsiderCandidateForRelationships(seedRow);

            return seedRow.Key;
        }
        /// <summary>
        /// Converts a potential HasStream annotation to the corresponding test annotation on the <paramref name="entityType"/>.
        /// </summary>
        /// <param name="entityType">EntityType to convert the annotations on.</param>
        private void ConvertHasStreamAnnotation(EntityType entityType)
        {
            ExceptionUtilities.CheckArgumentNotNull(entityType, "entityType");

            var hasStreamAnnotation = entityType.Annotations.OfType<AttributeAnnotation>()
                .Where(ann => ann.Content != null && ann.Content.Name.LocalName == "HasStream").SingleOrDefault();

            if (hasStreamAnnotation != null)
            {
                bool hasStreamValue = bool.Parse(hasStreamAnnotation.Content.Value);
                if (hasStreamValue)
                {
                    entityType.Add(new HasStreamAnnotation());
                }
            }
        }
 /// <summary>
 /// Visit entity type to convert annotations
 /// </summary>
 /// <param name="entity">Entity type to visit</param>
 protected override void VisitEntityType(EntityType entity)
 {
     this.ConvertHasStreamAnnotation(entity);
     base.VisitEntityType(entity);
 }
        private void CompareEntityTypes(EntityType expectedEntityType, EntityType actualEntityType)
        {
            string actualBaseTypeName = null;
            string expectedBaseTypeName = null;

            if (expectedEntityType.BaseType != null)
            {
                expectedBaseTypeName = expectedEntityType.BaseType.Name;
            }

            if (actualEntityType.BaseType != null)
            {
                actualBaseTypeName = actualEntityType.BaseType.Name;
            }

            this.WriteErrorIfFalse(expectedBaseTypeName == actualBaseTypeName, "EntityType BaseType property does not match Expected '{0}' Actual '{1}'", expectedBaseTypeName, actualBaseTypeName);

            this.CompareMemberProperties(expectedEntityType, expectedEntityType.Properties, actualEntityType.Properties);

            foreach (NavigationProperty navigationProperty in expectedEntityType.NavigationProperties)
            {
                List<NavigationProperty> actualNavProps = actualEntityType.NavigationProperties.Where(p => p.Name == navigationProperty.Name).ToList();
                if (!this.WriteErrorIfFalse(actualNavProps.Count == 1, "Cannot find NavProp '{0}'", navigationProperty.Name))
                {
                    NavigationProperty actualNavigationProperty = actualNavProps.Single();
                    this.CompareNavigationProperty(navigationProperty, actualNavigationProperty);
                }
            }
        }
Пример #30
0
 /// <summary>
 /// Generates 'EntityType' XElement based on <see cref="EntityType"/>.
 /// </summary>
 /// <param name="xmlNamespace">XML namespace to use</param>
 /// <param name="entityType">Entity type</param>
 /// <returns><see cref="XElement"/> representing EntityType.</returns>
 protected override XElement GenerateEntityType(XNamespace xmlNamespace, EntityType entityType)
 {
     var element = base.GenerateEntityType(xmlNamespace, entityType);
     TypeAccessModifierAnnotation annotation = entityType.Annotations.OfType<TypeAccessModifierAnnotation>().SingleOrDefault();
     element.Add(GenerateTypeAccessModifier(annotation));
     return element;
 }