Пример #1
0
 internal static void ValidateEntityTypeIsAssignable(IEdmEntityTypeReference expectedEntityTypeReference, IEdmEntityTypeReference payloadEntityTypeReference)
 {
     if (!expectedEntityTypeReference.EntityDefinition().IsAssignableFrom(payloadEntityTypeReference.EntityDefinition()))
     {
         throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_EntryTypeNotAssignableToExpectedType(payloadEntityTypeReference.ODataFullName(), expectedEntityTypeReference.ODataFullName()));
     }
 }
Пример #2
0
        private static object ConvertResource(ODataMessageReader oDataMessageReader, IEdmTypeReference edmTypeReference,
                                              ODataDeserializerContext readContext)
        {
            EdmEntitySet tempEntitySet = null;

            if (edmTypeReference.IsEntity())
            {
                IEdmEntityTypeReference entityType = edmTypeReference.AsEntity();
                tempEntitySet = new EdmEntitySet(readContext.Model.EntityContainer, "temp",
                                                 entityType.EntityDefinition());
            }

            // TODO: Sam xu, can we use the parameter-less overload
            ODataReader resourceReader = oDataMessageReader.CreateODataUriParameterResourceReader(tempEntitySet,
                                                                                                  edmTypeReference.ToStructuredType());

            object item = resourceReader.ReadResourceOrResourceSet();

            ODataResourceWrapper topLevelResource = item as ODataResourceWrapper;

            Contract.Assert(topLevelResource != null);

            ODataDeserializerProvider deserializerProvider = readContext.Request.GetDeserializerProvider();

            ODataResourceDeserializer entityDeserializer =
                (ODataResourceDeserializer)deserializerProvider.GetEdmTypeDeserializer(edmTypeReference);

            return(entityDeserializer.ReadInline(topLevelResource, edmTypeReference, readContext));
        }
Пример #3
0
        /// <summary>
        /// Returns whether or not the type is an entity or entity collection type.
        /// </summary>
        /// <param name="edmType">The type to check.</param>
        /// <param name="entityType">The entity type. If the given type was a collection, this will be the element type.</param>
        /// <returns>Whether or not the type is an entity or entity collection type.</returns>
        internal static bool IsEntityOrEntityCollectionType(this IEdmType edmType, out IEdmEntityType entityType)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(edmType != null, "targetEdmType != null");
            if (edmType.TypeKind == EdmTypeKind.Entity)
            {
                entityType = (IEdmEntityType)edmType;
                return(true);
            }

            if (edmType.TypeKind != EdmTypeKind.Collection)
            {
                entityType = null;
                return(false);
            }

            IEdmEntityTypeReference entityReference = ((IEdmCollectionType)edmType).ElementType as IEdmEntityTypeReference;

            if (entityReference == null)
            {
                entityType = null;
                return(false);
            }

            entityType = entityReference.EntityDefinition();
            return(true);
        }
Пример #4
0
        /// <summary>
        /// Deserializes the given <paramref name="entryWrapper"/> under the given <paramref name="readContext"/>.
        /// </summary>
        /// <param name="entryWrapper">The OData entry to deserialize.</param>
        /// <param name="entityType">The entity type of the entry to deserialize.</param>
        /// <param name="readContext">The deserializer context.</param>
        /// <returns>The deserialized entity.</returns>
        public virtual object ReadEntry(ODataEntryWithNavigationLinks entryWrapper, IEdmEntityTypeReference entityType,
                                        ODataDeserializerContext readContext)
        {
            if (entryWrapper == null)
            {
                throw Error.ArgumentNull("entryWrapper");
            }

            if (readContext == null)
            {
                throw Error.ArgumentNull("readContext");
            }

            if (!String.IsNullOrEmpty(entryWrapper.Entry.TypeName) && entityType.FullName() != entryWrapper.Entry.TypeName)
            {
                // received a derived type in a base type deserializer. delegate it to the appropriate derived type deserializer.
                IEdmModel model = readContext.Model;

                if (model == null)
                {
                    throw Error.Argument("readContext", SRResources.ModelMissingFromReadContext);
                }

                IEdmEntityType actualType = model.FindType(entryWrapper.Entry.TypeName) as IEdmEntityType;
                if (actualType == null)
                {
                    throw new ODataException(Error.Format(SRResources.EntityTypeNotInModel, entryWrapper.Entry.TypeName));
                }

                if (actualType.IsAbstract)
                {
                    string message = Error.Format(SRResources.CannotInstantiateAbstractEntityType, entryWrapper.Entry.TypeName);
                    throw new ODataException(message);
                }

                IEdmTypeReference        actualEntityType = new EdmEntityTypeReference(actualType, isNullable: false);
                ODataEdmTypeDeserializer deserializer     = DeserializerProvider.GetEdmTypeDeserializer(actualEntityType);
                if (deserializer == null)
                {
                    throw new SerializationException(
                              Error.Format(SRResources.TypeCannotBeDeserialized, actualEntityType.FullName(), typeof(ODataMediaTypeFormatter).Name));
                }

                object resource = deserializer.ReadInline(entryWrapper, actualEntityType, readContext);

                EdmStructuredObject structuredObject = resource as EdmStructuredObject;
                if (structuredObject != null)
                {
                    structuredObject.ExpectedEdmType = entityType.EntityDefinition();
                }

                return(resource);
            }
            else
            {
                object resource = CreateEntityResource(entityType, readContext);
                ApplyEntityProperties(resource, entryWrapper, entityType, readContext);
                return(resource);
            }
        }
Пример #5
0
        public void Index([FromBody] ODataUntypedActionParameters parameters)
        {
            IEdmModel model = Request.ODataProperties().Model;
            IEdmEntityTypeReference docTypeRef = model.GetDocTypeRef();
            IEdmEntityType          docType    = docTypeRef.EntityDefinition();

            IEdmEntityObject CopyDocument(IEdmComplexObject source)
            {
                var target = new EdmEntityObject(docTypeRef);

                foreach (string propertyName in docType.StructuralProperties().Select(p => p.Name))
                {
                    if (source.TryGetPropertyValue(propertyName, out object propertyValue))
                    {
                        target.TrySetPropertyValue(propertyName, propertyValue);
                    }
                }

                return(target);
            }

            var documentsObjects = (EdmComplexObjectCollection)parameters["value"];
            IEnumerable <IEdmEntityObject> documents = documentsObjects.Select(CopyDocument);

            Documents.AddRange(documents);
        }
        private EntityInstanceContext(ODataSerializerContext serializerContext, IEdmEntityTypeReference entityType, IEdmStructuredObject edmObject)
        {
            if (serializerContext == null)
            {
                throw Error.ArgumentNull("serializerContext");
            }

            SerializerContext = serializerContext;
            EntityType = entityType.EntityDefinition();
            EdmObject = edmObject;
        }
Пример #7
0
        private EntityInstanceContext(ODataSerializerContext serializerContext, IEdmEntityTypeReference entityType, IEdmEntityObject edmObject)
        {
            if (serializerContext == null)
            {
                throw Error.ArgumentNull("serializerContext");
            }

            SerializerContext = serializerContext;
            EntityType        = entityType.EntityDefinition();
            EdmObject         = edmObject;
        }
Пример #8
0
        /// <summary>
        /// Validates that the <paramref name="payloadEntityTypeReference"/> is assignable to the <paramref name="expectedEntityTypeReference"/>
        /// and fails if it's not.
        /// </summary>
        /// <param name="expectedEntityTypeReference">The expected entity type reference, the base type of the entities expected.</param>
        /// <param name="payloadEntityTypeReference">The payload entity type reference to validate.</param>
        internal static void ValidateEntityTypeIsAssignable(IEdmEntityTypeReference expectedEntityTypeReference, IEdmEntityTypeReference payloadEntityTypeReference)
        {
            Debug.Assert(expectedEntityTypeReference != null, "expectedEntityTypeReference != null");
            Debug.Assert(payloadEntityTypeReference != null, "payloadEntityTypeReference != null");

            // Entity types must be assignable
            if (!EdmLibraryExtensions.IsAssignableFrom(expectedEntityTypeReference.EntityDefinition(), payloadEntityTypeReference.EntityDefinition()))
            {
                throw new ODataException(Strings.ValidationUtils_ResourceTypeNotAssignableToExpectedType(payloadEntityTypeReference.FullName(), expectedEntityTypeReference.FullName()));
            }
        }
Пример #9
0
        private EntityInstanceContext(ODataSerializerContext serializerContext, IEdmEntityTypeReference entityType, IEdmEntityObject edmObject, string assemblyName)
        {
            if (serializerContext == null)
            {
                throw Error.ArgumentNull("serializerContext");
            }

	        AssemblyName = assemblyName;
            SerializerContext = serializerContext;
            EntityType = entityType.EntityDefinition();
            EdmObject = edmObject;
        }
Пример #10
0
            internal static object ConvertEntity(ODataMessageReader oDataMessageReader, IEdmTypeReference edmTypeReference,
                                                 ODataDeserializerContext readContext)
            {
                IEdmEntityTypeReference entityType = edmTypeReference.AsEntity();

                EdmEntitySet tempEntitySet = new EdmEntitySet(readContext.Model.EntityContainer, "temp",
                                                              entityType.EntityDefinition());

                ODataReader entryReader = oDataMessageReader.CreateODataEntryReader(tempEntitySet,
                                                                                    entityType.EntityDefinition());

                object item = ODataEntityDeserializer.ReadEntryOrFeed(entryReader);

                ODataEntryWithNavigationLinks topLevelEntry = item as ODataEntryWithNavigationLinks;

                Contract.Assert(topLevelEntry != null);

                ODataEntityDeserializer entityDeserializer =
                    (ODataEntityDeserializer)DeserializerProvider.GetEdmTypeDeserializer(entityType);
                object entity = entityDeserializer.ReadInline(topLevelEntry, entityType, readContext);

                return(CovertEntityId(entity, topLevelEntry.Entry, entityType, readContext));
            }
        private DataObject CreateDataObject(DataObjectEdmModel model, IEdmEntityTypeReference entityTypeReference, ODataEntryWithNavigationLinks entry, out Type objType)
        {
            IEdmEntityType entityType = entityTypeReference.EntityDefinition();

            objType = model.GetDataObjectType(model.GetEdmEntitySet(entityType).Name);
            var obj = (DataObject)Activator.CreateInstance(objType);

            foreach (ODataProperty odataProp in entry.Entry.Properties)
            {
                string clrPropName = model.GetDataObjectPropertyName(objType, odataProp.Name);
                Information.SetPropValueByName(obj, clrPropName, odataProp.Value);
            }

            return(obj);
        }
        private void WriteEntry(object graph, IEnumerable <ODataProperty> propertyBag, ODataWriter writer, ODataSerializerContext writeContext)
        {
            IEdmEntityType        entityType            = _edmEntityTypeReference.EntityDefinition();
            EntityInstanceContext entityInstanceContext = new EntityInstanceContext
            {
                EdmModel       = SerializerProvider.EdmModel,
                EntitySet      = writeContext.EntitySet,
                EntityType     = entityType,
                UrlHelper      = writeContext.UrlHelper,
                PathHandler    = writeContext.PathHandler,
                EntityInstance = graph,
                SkipExpensiveAvailabilityChecks = writeContext.SkipExpensiveAvailabilityChecks
            };

            ODataEntry entry = new ODataEntry
            {
                TypeName   = _edmEntityTypeReference.FullName(),
                Properties = propertyBag,
                Actions    = CreateActions(entityInstanceContext)
            };

            if (writeContext.EntitySet != null)
            {
                IEntitySetLinkBuilder linkBuilder = SerializerProvider.EdmModel.GetEntitySetLinkBuilder(writeContext.EntitySet);

                string idLink = linkBuilder.BuildIdLink(entityInstanceContext);
                if (idLink != null)
                {
                    entry.Id = idLink;
                }

                Uri readLink = linkBuilder.BuildReadLink(entityInstanceContext);
                if (readLink != null)
                {
                    entry.ReadLink = readLink;
                }

                Uri editLink = linkBuilder.BuildEditLink(entityInstanceContext);
                if (editLink != null)
                {
                    entry.EditLink = editLink;
                }
            }

            writer.WriteStart(entry);
            WriteNavigationLinks(entityInstanceContext, writer, writeContext);
            writer.WriteEnd();
        }
Пример #13
0
        public override object Read(ODataMessageReader messageReader, ODataDeserializerContext readContext)
        {
            if (messageReader == null)
            {
                throw Error.ArgumentNull("messageReader");
            }

            if (readContext == null)
            {
                throw Error.ArgumentNull("readContext");
            }

            ODataReader reader = messageReader.CreateODataFeedReader(_edmEntityType.EntityDefinition());
            ODataFeed   feed   = ODataEntityDeserializer.ReadEntryOrFeed(reader, readContext) as ODataFeed;

            return(ReadInline(feed, readContext));
        }
Пример #14
0
        /// <summary>
        /// If an entity type name is found in the payload this method is called to apply it to the current scope.
        /// This method should be called even if the type name was not found in which case a null should be passed in.
        /// The method validates that some type will be available as the current entity type after it returns (if we are parsing using metadata).
        /// </summary>
        /// <param name="entityTypeNameFromPayload">The entity type name found in the payload or null if no type was specified in the payload.</param>
        protected void ApplyEntityTypeNameFromPayload(string entityTypeNameFromPayload)
        {
            Debug.Assert(
                this.scopes.Count > 0 && this.scopes.Peek().Item is ODataEntry,
                "Entity type can be applied only when in entry scope.");

            SerializationTypeNameAnnotation serializationTypeNameAnnotation;
            EdmTypeKind             targetTypeKind;
            IEdmEntityTypeReference targetEntityTypeReference =
                (IEdmEntityTypeReference)ReaderValidationUtils.ResolvePayloadTypeNameAndComputeTargetType(
                    EdmTypeKind.Entity,
                    /*defaultPrimitivePayloadType*/ null,
                    this.CurrentEntityType.ToTypeReference(),
                    entityTypeNameFromPayload,
                    this.inputContext.Model,
                    this.inputContext.MessageReaderSettings,
                    this.inputContext.Version,
                    () => EdmTypeKind.Entity,
                    out targetTypeKind,
                    out serializationTypeNameAnnotation);

            IEdmEntityType targetEntityType = null;
            ODataEntry     entry            = this.CurrentEntry;

            if (targetEntityTypeReference != null)
            {
                targetEntityType = targetEntityTypeReference.EntityDefinition();
                entry.TypeName   = targetEntityType.ODataFullName();

                if (serializationTypeNameAnnotation != null)
                {
                    entry.SetAnnotation(serializationTypeNameAnnotation);
                }
            }
            else if (entityTypeNameFromPayload != null)
            {
                entry.TypeName = entityTypeNameFromPayload;
            }

            // Set the current entity type since the type from payload might be more derived than
            // the expected one.
            this.CurrentEntityType = targetEntityType;
        }
Пример #15
0
        /// <summary>
        /// Binds key values to a key lookup on a collection.
        /// </summary>
        /// <param name="collectionNode">Already bound collection node.</param>
        /// <param name="namedValues">The named value tokens to bind.</param>
        /// <returns>The bound key lookup.</returns>
        internal QueryNode BindKeyValues(EntityCollectionNode collectionNode, IEnumerable <NamedValue> namedValues)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(namedValues != null, "namedValues != null");
            Debug.Assert(collectionNode != null, "CollectionNode != null");

            IEdmEntityTypeReference collectionItemType = collectionNode.EntityItemType;
            List <KeyPropertyValue> keyPropertyValues  = new List <KeyPropertyValue>();

            IEdmEntityType collectionItemEntityType = collectionItemType.EntityDefinition();

            HashSet <string> keyPropertyNames = new HashSet <string>(StringComparer.Ordinal);

            foreach (NamedValue namedValue in namedValues)
            {
                KeyPropertyValue keyPropertyValue = this.BindKeyPropertyValue(namedValue, collectionItemEntityType);
                Debug.Assert(keyPropertyValue != null, "keyPropertyValue != null");
                Debug.Assert(keyPropertyValue.KeyProperty != null, "keyPropertyValue.KeyProperty != null");

                if (!keyPropertyNames.Add(keyPropertyValue.KeyProperty.Name))
                {
                    throw new ODataException(ODataErrorStrings.MetadataBinder_DuplicitKeyPropertyInKeyValues(keyPropertyValue.KeyProperty.Name));
                }

                keyPropertyValues.Add(keyPropertyValue);
            }

            if (keyPropertyValues.Count == 0)
            {
                // No key values specified, for example '/Customers()', do not include the key lookup at all
                return(collectionNode);
            }
            else if (keyPropertyValues.Count != collectionItemEntityType.Key().Count())
            {
                throw new ODataException(ODataErrorStrings.MetadataBinder_NotAllKeyPropertiesSpecifiedInKeyValues(collectionNode.ItemType.ODataFullName()));
            }
            else
            {
                return(new KeyLookupNode(collectionNode, new ReadOnlyCollection <KeyPropertyValue>(keyPropertyValues)));
            }
        }
        /// <summary>
        /// Creates a new instance of the <see cref="SelectExpandNode"/> class describing the set of structural properties,
        /// navigation properties, and actions to select and expand for the given <paramref name="selectExpandClause"/>.
        /// </summary>
        /// <param name="selectExpandClause">The parsed $select and $expand query options.</param>
        /// <param name="entityType">The entity type of the entry that would be written.</param>
        /// <param name="model">The <see cref="IEdmModel"/> that contains the given entity type.</param>
        public SelectExpandNode(SelectExpandClause selectExpandClause, IEdmEntityTypeReference entityType, IEdmModel model)
            : this()
        {
            if (entityType == null)
            {
                throw Error.ArgumentNull("entityType");
            }
            if (model == null)
            {
                throw Error.ArgumentNull("model");
            }

            HashSet<IEdmStructuralProperty> allStructuralProperties = new HashSet<IEdmStructuralProperty>(entityType.StructuralProperties());
            HashSet<IEdmNavigationProperty> allNavigationProperties = new HashSet<IEdmNavigationProperty>(entityType.NavigationProperties());
            HashSet<IEdmFunctionImport> allActions = new HashSet<IEdmFunctionImport>(model.GetAvailableProcedures(entityType.EntityDefinition()));

            if (selectExpandClause == null)
            {
                SelectedStructuralProperties = allStructuralProperties;
                SelectedNavigationProperties = allNavigationProperties;
                SelectedActions = allActions;
            }
            else
            {
                if (selectExpandClause.AllSelected)
                {
                    SelectedStructuralProperties = allStructuralProperties;
                    SelectedNavigationProperties = allNavigationProperties;
                    SelectedActions = allActions;
                }
                else
                {
                    BuildSelections(selectExpandClause, allStructuralProperties, allNavigationProperties, allActions);
                }

                BuildExpansions(selectExpandClause, allNavigationProperties);

                // remove expanded navigation properties from the selected navigation properties.
                SelectedNavigationProperties.ExceptWith(ExpandedNavigationProperties.Keys);
            }
        }
Пример #17
0
        // Get entityset
        // odata/{datasource}/{entityset}
        public EdmEntityObjectCollection Get(string datasource)
        {
            // Get entity set's EDM type: A collection type.
            ODataPath               path                   = Request.ODataFeature().Path;
            IEdmCollectionType      collectionType         = (IEdmCollectionType)path.Last().EdmType;
            IEdmEntityTypeReference edmEntityTypeReference = collectionType.ElementType.AsEntity();
            var edmEntityType = edmEntityTypeReference.EntityDefinition();

            //Set the SelectExpandClause on OdataFeature to include navigation property set in the $expand
            SetSelectExpandClauseOnODataFeature(path, edmEntityType);

            // Create an untyped collection with the EDM collection type.
            EdmEntityObjectCollection collection =
                new EdmEntityObjectCollection(new EdmCollectionTypeReference(collectionType));

            // Add untyped objects to collection.
            IDataSource ds = _provider.DataSources[datasource];

            ds.Get(edmEntityTypeReference, collection);

            return(collection);
        }
        private void WriteEntry(object graph, IEnumerable <ODataProperty> propertyBag, ODataWriter writer, ODataSerializerContext writeContext)
        {
            IEdmEntityType        entityType            = _edmEntityTypeReference.EntityDefinition();
            EntityInstanceContext entityInstanceContext = new EntityInstanceContext(SerializerProvider.EdmModel, writeContext.EntitySet, entityType, writeContext.UrlHelper, graph);

            ODataEntry entry = new ODataEntry
            {
                TypeName   = _edmEntityTypeReference.FullName(),
                Properties = propertyBag,
            };

            if (writeContext.EntitySet != null)
            {
                IEntitySetLinkBuilder linkBuilder = SerializerProvider.EdmModel.GetEntitySetLinkBuilder(writeContext.EntitySet);

                string idLink = linkBuilder.BuildIdLink(entityInstanceContext);
                if (idLink != null)
                {
                    entry.Id = idLink;
                }

                Uri readLink = linkBuilder.BuildReadLink(entityInstanceContext);
                if (readLink != null)
                {
                    entry.ReadLink = readLink;
                }

                Uri editLink = linkBuilder.BuildEditLink(entityInstanceContext);
                if (editLink != null)
                {
                    entry.EditLink = editLink;
                }
            }

            writer.WriteStart(entry);
            WriteNavigationLinks(entityInstanceContext, writer, writeContext);
            writer.WriteEnd();
        }
Пример #19
0
        protected void ApplyEntityTypeNameFromPayload(string entityTypeNameFromPayload)
        {
            SerializationTypeNameAnnotation annotation;
            EdmTypeKind             kind;
            IEdmEntityTypeReference reference = (IEdmEntityTypeReference)ReaderValidationUtils.ResolvePayloadTypeNameAndComputeTargetType(EdmTypeKind.Entity, null, this.CurrentEntityType.ToTypeReference(), entityTypeNameFromPayload, this.inputContext.Model, this.inputContext.MessageReaderSettings, this.inputContext.Version, () => EdmTypeKind.Entity, out kind, out annotation);
            IEdmEntityType          type      = null;
            ODataEntry currentEntry           = this.CurrentEntry;

            if (reference != null)
            {
                type = reference.EntityDefinition();
                currentEntry.TypeName = type.ODataFullName();
                if (annotation != null)
                {
                    currentEntry.SetAnnotation <SerializationTypeNameAnnotation>(annotation);
                }
            }
            else if (entityTypeNameFromPayload != null)
            {
                currentEntry.TypeName = entityTypeNameFromPayload;
            }
            this.CurrentEntityType = type;
        }
Пример #20
0
        /// <summary>
        /// Binds key values to a key lookup on a collection.
        /// </summary>
        /// <param name="collectionNode">Already bound collection node.</param>
        /// <param name="namedValues">The named value tokens to bind.</param>
        /// <param name="model">The model to be used.</param>
        /// <returns>The bound key lookup.</returns>
        internal QueryNode BindKeyValues(CollectionResourceNode collectionNode, IEnumerable <NamedValue> namedValues, IEdmModel model)
        {
            Debug.Assert(namedValues != null, "namedValues != null");
            Debug.Assert(collectionNode != null, "CollectionNode != null");
            Debug.Assert(model != null, "model != null");

            IEdmEntityTypeReference collectionItemType = collectionNode.ItemStructuredType as IEdmEntityTypeReference;

            IEdmEntityType collectionItemEntityType = collectionItemType.EntityDefinition();
            QueryNode      keyLookupNode;

            if (TryBindToDeclaredKey(collectionNode, namedValues, model, collectionItemEntityType, out keyLookupNode))
            {
                return(keyLookupNode);
            }
            else if (TryBindToDeclaredAlternateKey(collectionNode, namedValues, model, collectionItemEntityType, out keyLookupNode))
            {
                return(keyLookupNode);
            }
            else
            {
                throw new ODataException(ODataErrorStrings.MetadataBinder_NotAllKeyPropertiesSpecifiedInKeyValues(collectionNode.ItemStructuredType.FullName()));
            }
        }
Пример #21
0
        /// <summary>
        /// Creates a new instance of the <see cref="SelectExpandNode"/> class describing the set of structural properties,
        /// navigation properties, and actions to select and expand for the given <paramref name="selectExpandClause"/>.
        /// </summary>
        /// <param name="selectExpandClause">The parsed $select and $expand query options.</param>
        /// <param name="entityType">The entity type of the entry that would be written.</param>
        /// <param name="model">The <see cref="IEdmModel"/> that contains the given entity type.</param>
        public SelectExpandNode(SelectExpandClause selectExpandClause, IEdmEntityTypeReference entityType, IEdmModel model)
            : this()
        {
            if (entityType == null)
            {
                throw Error.ArgumentNull("entityType");
            }
            if (model == null)
            {
                throw Error.ArgumentNull("model");
            }

            HashSet <IEdmStructuralProperty> allStructuralProperties = new HashSet <IEdmStructuralProperty>(entityType.StructuralProperties());
            HashSet <IEdmNavigationProperty> allNavigationProperties = new HashSet <IEdmNavigationProperty>(entityType.NavigationProperties());
            HashSet <IEdmFunctionImport>     allActions = new HashSet <IEdmFunctionImport>(model.GetAvailableProcedures(entityType.EntityDefinition()));

            if (selectExpandClause == null)
            {
                SelectedStructuralProperties = allStructuralProperties;
                SelectedNavigationProperties = allNavigationProperties;
                SelectedActions = allActions;
            }
            else
            {
                if (selectExpandClause.AllSelected)
                {
                    SelectedStructuralProperties = allStructuralProperties;
                    SelectedNavigationProperties = allNavigationProperties;
                    SelectedActions = allActions;
                }
                else
                {
                    BuildSelections(selectExpandClause, allStructuralProperties, allNavigationProperties, allActions);
                }

                BuildExpansions(selectExpandClause, allNavigationProperties);

                // remove expanded navigation properties from the selected navigation properties.
                SelectedNavigationProperties.ExceptWith(ExpandedNavigationProperties.Keys);
            }
        }
Пример #22
0
 internal static void ValidateEntityTypeIsAssignable(IEdmEntityTypeReference expectedEntityTypeReference, IEdmEntityTypeReference payloadEntityTypeReference)
 {
     if (!expectedEntityTypeReference.EntityDefinition().IsAssignableFrom(payloadEntityTypeReference.EntityDefinition()))
     {
         throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_EntryTypeNotAssignableToExpectedType(payloadEntityTypeReference.ODataFullName(), expectedEntityTypeReference.ODataFullName()));
     }
 }
Пример #23
0
        /// <inheritdoc />
        public override void WriteObject(object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)
        {
            if (messageWriter == null)
            {
                throw Error.ArgumentNull("messageWriter");
            }

            if (writeContext == null)
            {
                throw Error.ArgumentNull("writeContext");
            }

            IEdmEntitySetBase entitySet = writeContext.NavigationSource as IEdmEntitySetBase;

            IEdmTypeReference feedType = writeContext.GetEdmType(graph, type);

            Contract.Assert(feedType != null);

            IEdmEntityTypeReference entityType = GetEntityType(feedType);
            ODataWriter             writer     = messageWriter.CreateODataFeedWriter(entitySet, entityType.EntityDefinition());

            WriteObjectInline(graph, feedType, writer, writeContext);
        }
 protected override void ProcessEntityTypeReference(IEdmEntityTypeReference element)
 {
     this.CheckSchemaElementReference(element.EntityDefinition());
 }
        /// <inheritdoc />
        public override async Task WriteObjectAsync(object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)
        {
            if (messageWriter == null)
            {
                throw Error.ArgumentNull(nameof(messageWriter));
            }

            if (writeContext == null)
            {
                throw Error.ArgumentNull(nameof(writeContext));
            }

            if (graph == null)
            {
                throw new SerializationException(Error.Format(SRResources.CannotSerializerNull, DeltaFeed));
            }

            IEdmEntitySetBase entitySet = writeContext.NavigationSource as IEdmEntitySetBase;

            if (entitySet == null)
            {
                throw new SerializationException(SRResources.EntitySetMissingDuringSerialization);
            }

            IEdmTypeReference feedType = writeContext.GetEdmType(graph, type);

            Contract.Assert(feedType != null);

            IEdmEntityTypeReference entityType = GetResourceType(feedType).AsEntity();
            ODataWriter             writer     = await messageWriter.CreateODataDeltaResourceSetWriterAsync(entitySet, entityType.EntityDefinition())
                                                 .ConfigureAwait(false);

            await WriteDeltaFeedInlineAsync(graph, feedType, writer, writeContext).ConfigureAwait(false);
        }
Пример #26
0
        /// <summary>
        /// Combines the property types and returns a reference to the resulting facade.
        /// </summary>
        /// <param name="propertyName">The name of the navigation properties being combined. Used only for error messages.</param>
        /// <param name="clientProperty">The client property.</param>
        /// <param name="serverProperty">The server property.</param>
        /// <param name="modelFacade">The model facade.</param>
        /// <returns>
        /// A type reference to the combined type.
        /// </returns>
        private static IEdmTypeReference CombinePropertyTypes(string propertyName, IEdmNavigationProperty clientProperty, IEdmNavigationProperty serverProperty, EdmModelFacade modelFacade)
        {
            Debug.Assert(clientProperty != null, "clientProperty != null");
            Debug.Assert(serverProperty != null, "serverProperty != null");

            IEdmTypeReference clientPropertyType = clientProperty.Type;
            IEdmTypeReference serverPropertyType = serverProperty.Type;

            // ensure that either both sides are a collection or neither is.
            IEdmCollectionTypeReference clientCollectionType = clientPropertyType as IEdmCollectionTypeReference;
            IEdmCollectionTypeReference serverCollectionType = serverPropertyType as IEdmCollectionTypeReference;
            bool isCollection = clientCollectionType != null;

            if (isCollection != (serverCollectionType != null))
            {
                throw new InvalidOperationException(ErrorStrings.EdmNavigationPropertyFacade_InconsistentMultiplicity(propertyName));
            }

            // For collection properties: extract the element types, combine them, then recreate the collection.
            // For reference properties: get the entity types and combine them.
            IEdmType combinedType;

            if (isCollection)
            {
                // get the client element type and ensure it's an entity type.
                IEdmEntityTypeReference clientElementTypeReference = clientCollectionType.ElementType() as IEdmEntityTypeReference;
                if (clientElementTypeReference == null)
                {
                    throw new InvalidOperationException(ErrorStrings.EdmNavigationPropertyFacade_NonEntityType(propertyName, clientProperty.DeclaringType.FullName()));
                }

                // get the server element type and ensure it's an entity type.
                IEdmEntityTypeReference serverElementTypeReference = serverCollectionType.ElementType() as IEdmEntityTypeReference;
                if (serverElementTypeReference == null)
                {
                    throw new InvalidOperationException(ErrorStrings.EdmNavigationPropertyFacade_NonEntityType(propertyName, serverProperty.DeclaringType.FullName()));
                }

                // combine the element types.
                combinedType = modelFacade.CombineWithServerType(clientElementTypeReference.EntityDefinition(), serverElementTypeReference.EntityDefinition());

                // turn it back into a collection, maintaining nullability of the client's element type.
                combinedType = new EdmCollectionType(combinedType.ToEdmTypeReference(clientElementTypeReference.IsNullable));
            }
            else
            {
                // ensure the server property type is an entity type.
                IEdmEntityTypeReference clientEntityTypeReference = clientPropertyType as IEdmEntityTypeReference;
                if (clientEntityTypeReference == null)
                {
                    throw new InvalidOperationException(ErrorStrings.EdmNavigationPropertyFacade_NonEntityType(propertyName, clientProperty.DeclaringType.FullName()));
                }

                // ensure the server property type is an entity type.
                IEdmEntityTypeReference serverEntityTypeReference = serverPropertyType as IEdmEntityTypeReference;
                if (serverEntityTypeReference == null)
                {
                    throw new InvalidOperationException(ErrorStrings.EdmNavigationPropertyFacade_NonEntityType(propertyName, serverProperty.DeclaringType.FullName()));
                }

                combinedType = modelFacade.CombineWithServerType(clientEntityTypeReference.EntityDefinition(), serverEntityTypeReference.EntityDefinition());
            }

            // return a type reference, maintaining the original nullability from the client property type.
            return(combinedType.ToEdmTypeReference(clientPropertyType.IsNullable));
        }
Пример #27
0
        private void BuildEdmModel()
        {
            _entityType = new EdmEntityTypeReference(new EdmEntityType("NS", "Entity"), isNullable: false);
            _derivedEntityType = new EdmEntityTypeReference(new EdmEntityType("NS", "DerivedEntity", _entityType.EntityDefinition()), isNullable: false);
            var entityCollection = new EdmCollectionTypeReference(new EdmCollectionType(_entityType));
            var derivedEntityCollection = new EdmCollectionTypeReference(new EdmCollectionType(_derivedEntityType));

            EdmModel model = new EdmModel();
            EdmEntityContainer container = new EdmEntityContainer("NS", "Name");
            model.AddElement(container);

            // non-bindable action
            container.AddActionImport(new EdmAction("NS", "NonBindableAction", returnType: null));

            // action bound to entity
            var actionBoundToEntity = new EdmAction(
                "NS",
                "ActionBoundToEntity",
                returnType: null,
                isBound: true,
                entitySetPathExpression: null);
            actionBoundToEntity.AddParameter("bindingParameter", _entityType);
            model.AddElement(actionBoundToEntity);

            // action bound to derived entity
            var actionBoundToDerivedEntity = new EdmAction(
                "NS",
                "ActionBoundToDerivedEntity",
                returnType: null,
                isBound: true,
                entitySetPathExpression: null);
            actionBoundToDerivedEntity.AddParameter("bindingParameter", _derivedEntityType);
            model.AddElement(actionBoundToDerivedEntity);

            // action bound to entity collection
            var actionBoundToEntityCollection = new EdmAction(
                "NS",
                "ActionBoundToEntityCollection",
                returnType: null,
                isBound: true,
                entitySetPathExpression: null);
            actionBoundToEntityCollection.AddParameter("bindingParameter", entityCollection);
            model.AddElement(actionBoundToEntityCollection);

            // action bound to derived entity collection
            var actionBoundToDerivedEntityCollection = new EdmAction(
                "NS",
                "ActionBoundToDerivedEntityCollection",
                returnType: null,
                isBound: true,
                entitySetPathExpression: null);
            actionBoundToDerivedEntityCollection.AddParameter("bindingParameter", derivedEntityCollection);
            model.AddElement(actionBoundToDerivedEntityCollection);

            // ambiguos actions
            container.AddActionImport(new EdmAction("NS", "AmbiguousAction", returnType: null));
            container.AddActionImport(new EdmAction("NS", "AmbiguousAction", returnType: null));

            IEdmTypeReference returnType = new EdmPrimitiveTypeReference(
                EdmCoreModel.Instance.GetPrimitiveType(EdmPrimitiveTypeKind.Int32), false);

            // non-bindable function
            container.AddFunctionImport(new EdmFunction("NS", "NonBindableFunction", returnType));

            // function bound to entity
            var functionBoundToEntity = new EdmFunction(
                "NS",
                "FunctionBoundToEntity",
                returnType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);
            functionBoundToEntity.AddParameter("bindingParameter", _entityType);
            model.AddElement(functionBoundToEntity);

            // function bound to entity
            var functionBoundToDerivedEntity = new EdmFunction(
                "NS",
                "FunctionBoundToDerivedEntity",
                returnType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);
            functionBoundToDerivedEntity.AddParameter("bindingParameter", _derivedEntityType);
            model.AddElement(functionBoundToDerivedEntity);

            // function bound to entity collection
            var functionBoundToEntityCollection = new EdmFunction(
                "NS",
                "FunctionBoundToEntityCollection",
                returnType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);
            functionBoundToEntityCollection.AddParameter("bindingParameter", entityCollection);
            model.AddElement(functionBoundToEntityCollection);

            // function bound to derived entity collection
            var functionBoundToDerivedEntityCollection = new EdmFunction(
                "NS",
                "FunctionBoundToDerivedEntityCollection",
                returnType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);
            functionBoundToDerivedEntityCollection.AddParameter("bindingParameter", derivedEntityCollection);
            model.AddElement(functionBoundToDerivedEntityCollection);

            _model = model;
            _container = container;
        }
Пример #28
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EdmStructuredObject"/> class.
 /// </summary>
 /// <param name="edmType">The <see cref="IEdmEntityTypeReference"/> of this object.</param>
 public EdmEntityObject(IEdmEntityTypeReference edmType)
     : this(edmType.EntityDefinition(), edmType.IsNullable)
 {
 }
Пример #29
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EdmStructuredObject"/> class.
 /// </summary>
 /// <param name="edmType">The <see cref="IEdmEntityTypeReference"/> of this object.</param>
 /// <param name="assembliesResolver">The assemblies resolve to use for type resolution</param>
 public EdmEntityObject(IEdmEntityTypeReference edmType, AssembliesResolver assembliesResolver)
     : this(edmType.EntityDefinition(), assembliesResolver, edmType.IsNullable)
 {
 }
Пример #30
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EdmDeltaDeletedEntityObject"/> class.
 /// </summary>
 /// <param name="entityTypeReference">The <see cref="IEdmEntityTypeReference"/> of this DeltaDeletedEntityObject.</param>
 public EdmDeltaDeletedEntityObject(IEdmEntityTypeReference entityTypeReference, AssembliesResolver assembliesResolver)
     : this(entityTypeReference.EntityDefinition(), assembliesResolver, entityTypeReference.IsNullable)
 {
 }
Пример #31
0
 public EdmDeltaLink(IEdmEntityTypeReference entityTypeReference)
     : this(entityTypeReference.EntityDefinition(), entityTypeReference.IsNullable)
 {
 }
Пример #32
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EdmDeltaEntityObject"/> class.
 /// </summary>
 /// <param name="entityTypeReference">The <see cref="IEdmEntityTypeReference"/> of this DeltaEntityObject.</param>
 public EdmDeltaEntityObject(IEdmEntityTypeReference entityTypeReference)
     : this(entityTypeReference.EntityDefinition(), entityTypeReference.IsNullable)
 {
 }
Пример #33
0
        /// <inheritdoc />
        public override object Read(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext)
        {
            if (messageReader == null)
            {
                throw Error.ArgumentNull("messageReader");
            }

            if (readContext == null)
            {
                throw Error.ArgumentNull("readContext");
            }

            if (readContext.Path == null)
            {
                throw Error.Argument("readContext", SRResources.ODataPathMissing);
            }

            IEdmEntitySet entitySet = GetEntitySet(readContext.Path);

            if (entitySet == null)
            {
                throw new SerializationException(SRResources.EntitySetMissingDuringDeserialization);
            }

            IEdmTypeReference edmType = readContext.GetEdmType(type);

            Contract.Assert(edmType != null);

            if (!edmType.IsEntity())
            {
                throw Error.Argument("type", SRResources.ArgumentMustBeOfType, EdmTypeKind.Entity);
            }

            IEdmEntityTypeReference entityType = edmType.AsEntity();

            ODataReader odataReader = messageReader.CreateODataEntryReader(entitySet, entityType.EntityDefinition());
            ODataEntryWithNavigationLinks topLevelEntry = ReadEntryOrFeed(odataReader) as ODataEntryWithNavigationLinks;

            Contract.Assert(topLevelEntry != null);

            return(ReadInline(topLevelEntry, entityType, readContext));
        }
Пример #34
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EdmStructuredObject"/> class.
 /// </summary>
 /// <param name="edmType">The <see cref="IEdmEntityTypeReference"/> of this object.</param>
 public EdmEntityObject(IEdmEntityTypeReference edmType)
     : this(edmType.EntityDefinition(), edmType.IsNullable)
 {
 }
Пример #35
0
		/// <summary>
		/// Initializes a new instance of the <see cref="EdmStructuredObject"/> class.
		/// </summary>
		/// <param name="edmType">The <see cref="IEdmEntityTypeReference"/> of this object.</param>
		/// <param name="assembliesResolver">The assemblies resolve to use for type resolution</param>
		public EdmEntityObject(IEdmEntityTypeReference edmType, AssembliesResolver assembliesResolver)
            : this(edmType.EntityDefinition(), assembliesResolver, edmType.IsNullable)
        {
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="EdmDeltaDeletedEntityObject"/> class.
 /// </summary>
 /// <param name="entityTypeReference">The <see cref="IEdmEntityTypeReference"/> of this DeltaDeletedEntityObject.</param>
 public EdmDeltaDeletedEntityObject(IEdmEntityTypeReference entityTypeReference, AssembliesResolver assembliesResolver)
     : this(entityTypeReference.EntityDefinition(), assembliesResolver, entityTypeReference.IsNullable)
 {
 }
        /// <summary>
        /// Deserializes the given <paramref name="entryWrapper"/> under the given <paramref name="readContext"/>.
        /// </summary>
        /// <param name="entryWrapper">The OData entry to deserialize.</param>
        /// <param name="entityType">The entity type of the entry to deserialize.</param>
        /// <param name="readContext">The deserializer context.</param>
        /// <returns>The deserialized entity.</returns>
        public virtual object ReadEntry(ODataEntryWithNavigationLinks entryWrapper, IEdmEntityTypeReference entityType,
            ODataDeserializerContext readContext)
        {
            if (entryWrapper == null)
            {
                throw Error.ArgumentNull("entryWrapper");
            }

            if (readContext == null)
            {
                throw Error.ArgumentNull("readContext");
            }

            if (!String.IsNullOrEmpty(entryWrapper.Entry.TypeName) && entityType.FullName() != entryWrapper.Entry.TypeName)
            {
                // received a derived type in a base type deserializer. delegate it to the appropriate derived type deserializer.
                IEdmModel model = readContext.Model;

                if (model == null)
                {
                    throw Error.Argument("readContext", SRResources.ModelMissingFromReadContext);
                }

                IEdmEntityType actualType = model.FindType(entryWrapper.Entry.TypeName) as IEdmEntityType;
                if (actualType == null)
                {
                    throw new ODataException(Error.Format(SRResources.EntityTypeNotInModel, entryWrapper.Entry.TypeName));
                }

                if (actualType.IsAbstract)
                {
                    string message = Error.Format(SRResources.CannotInstantiateAbstractEntityType, entryWrapper.Entry.TypeName);
                    throw new ODataException(message);
                }

                IEdmTypeReference actualEntityType = new EdmEntityTypeReference(actualType, isNullable: false);
                ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(actualEntityType);
                if (deserializer == null)
                {
                    throw new SerializationException(
                        Error.Format(SRResources.TypeCannotBeDeserialized, actualEntityType.FullName(), typeof(ODataMediaTypeFormatter).Name));
                }

                object resource = deserializer.ReadInline(entryWrapper, actualEntityType, readContext);

                EdmStructuredObject structuredObject = resource as EdmStructuredObject;
                if (structuredObject != null)
                {
                    structuredObject.ExpectedEdmType = entityType.EntityDefinition();
                }

                return resource;
            }
            else
            {
                object resource = CreateEntityResource(entityType, readContext);
                ApplyEntityProperties(resource, entryWrapper, entityType, readContext);
                return resource;
            }
        }
Пример #38
0
        /// <inheritdoc />
        public override void WriteObject(object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)
        {
            if (messageWriter == null)
            {
                throw Error.ArgumentNull("messageWriter");
            }

            if (writeContext == null)
            {
                throw Error.ArgumentNull("writeContext");
            }

            if (graph == null)
            {
                throw new SerializationException(Error.Format(SRResources.CannotSerializerNull, DeltaFeed));
            }

            IEdmEntitySetBase entitySet = writeContext.NavigationSource as IEdmEntitySetBase;

            if (entitySet == null)
            {
                throw new SerializationException(SRResources.EntitySetMissingDuringSerialization);
            }

            IEdmTypeReference feedType = writeContext.GetEdmType(graph, type);

            Contract.Assert(feedType != null);

            IEdmEntityTypeReference entityType = GetEntityType(feedType);
            ODataDeltaWriter        writer     = messageWriter.CreateODataDeltaWriter(entitySet, entityType.EntityDefinition());

            WriteDeltaFeedInline(graph, feedType, writer, writeContext);
        }
Пример #39
0
        /// <summary>
        /// Validates that the <paramref name="payloadEntityTypeReference"/> is assignable to the <paramref name="expectedEntityTypeReference"/>
        /// and fails if it's not.
        /// </summary>
        /// <param name="expectedEntityTypeReference">The expected entity type reference, the base type of the entities expected.</param>
        /// <param name="payloadEntityTypeReference">The payload entity type reference to validate.</param>
        internal static void ValidateEntityTypeIsAssignable(IEdmEntityTypeReference expectedEntityTypeReference, IEdmEntityTypeReference payloadEntityTypeReference)
        {
            Debug.Assert(expectedEntityTypeReference != null, "expectedEntityTypeReference != null");
            Debug.Assert(payloadEntityTypeReference != null, "payloadEntityTypeReference != null");

            // Entity types must be assignable
            if (!EdmLibraryExtensions.IsAssignableFrom(expectedEntityTypeReference.EntityDefinition(), payloadEntityTypeReference.EntityDefinition()))
            {
                throw new ODataException(Strings.ValidationUtils_EntryTypeNotAssignableToExpectedType(payloadEntityTypeReference.ODataFullName(), expectedEntityTypeReference.ODataFullName()));
            }
        }
Пример #40
0
        /// <summary>
        /// Writes the entity collection results to the response message.
        /// </summary>
        /// <param name="graph">The entity collection results.</param>
        /// <param name="type">The type of the entities.</param>
        /// <param name="messageWriter">The message writer.</param>
        /// <param name="writeContext">The writing context.</param>
        public override void WriteObject(
            object graph,
            Type type,
            ODataMessageWriter messageWriter,
            ODataSerializerContext writeContext)
        {
            Ensure.NotNull(messageWriter, "messageWriter");
            Ensure.NotNull(writeContext, "writeContext");

            IEdmEntitySetBase entitySet = writeContext.NavigationSource as IEdmEntitySetBase;

            if (entitySet == null)
            {
                throw new SerializationException(Resources.EntitySetMissingForSerialization);
            }

            EntityCollectionResult collectionResult = (EntityCollectionResult)graph;
            IEdmTypeReference      feedType         = collectionResult.EdmType;

            IEdmEntityTypeReference entityType = GetEntityType(feedType);
            ODataWriter             writer     = messageWriter.CreateODataFeedWriter(entitySet, entityType.EntityDefinition());

            this.WriteObjectInline(collectionResult.Query, feedType, writer, writeContext);
        }
 protected override void ProcessEntityTypeReference(IEdmEntityTypeReference element)
 {
     this.CheckSchemaElementReference(element.EntityDefinition());
 }
Пример #42
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EdmDeltaDeletedLink"/> class.
 /// </summary>
 /// <param name="entityTypeReference">The <see cref="IEdmEntityTypeReference"/> of this DeltaDeletedLink.</param>
 public EdmDeltaDeletedLink(IEdmEntityTypeReference entityTypeReference)
     : this(entityTypeReference.EntityDefinition(), entityTypeReference.IsNullable)
 {
 }
Пример #43
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EdmDeltaDeletedEntityObject"/> class.
 /// </summary>
 /// <param name="entityTypeReference">The <see cref="IEdmEntityTypeReference"/> of this DeltaDeletedEntityObject.</param>
 public EdmDeltaDeletedEntityObject(IEdmEntityTypeReference entityTypeReference)
     : this(entityTypeReference.EntityDefinition(), entityTypeReference.IsNullable)
 {
 }
Пример #44
0
        private void BuildSelections(Selection selection, IEdmEntityTypeReference entityType, IEdmModel model)
        {
            Contract.Assert(entityType != null);
            Contract.Assert(model != null);

            HashSet<IEdmStructuralProperty> allStructuralProperties = new HashSet<IEdmStructuralProperty>(entityType.StructuralProperties());
            HashSet<IEdmNavigationProperty> allNavigationProperties = new HashSet<IEdmNavigationProperty>(entityType.NavigationProperties());
            HashSet<IEdmFunctionImport> allActions = new HashSet<IEdmFunctionImport>(model.GetAvailableProcedures(entityType.EntityDefinition()));

            if (selection == null || selection == AllSelection.Instance)
            {
                SelectedStructuralProperties = allStructuralProperties;
                SelectedNavigationProperties = allNavigationProperties;
                SelectedActions = allActions;
            }
            else if (selection == ExpansionsOnly.Instance)
            {
                // nothing to select.
            }
            else
            {
                PartialSelection partialSelection = selection as PartialSelection;
                if (partialSelection == null)
                {
                    throw new ODataException(Error.Format(SRResources.SelectionTypeNotSupported, selection.GetType().Name));
                }

                HashSet<IEdmStructuralProperty> selectedStructuralProperties = new HashSet<IEdmStructuralProperty>();
                HashSet<IEdmNavigationProperty> selectedNavigationProperties = new HashSet<IEdmNavigationProperty>();
                HashSet<IEdmFunctionImport> selectedActions = new HashSet<IEdmFunctionImport>();

                foreach (SelectionItem selectionItem in partialSelection.SelectedItems)
                {
                    PathSelectionItem pathSelection = selectionItem as PathSelectionItem;

                    if (pathSelection != null)
                    {
                        ValidatePathIsSupported(pathSelection.SelectedPath);
                        Segment segment = pathSelection.SelectedPath.LastSegment;

                        NavigationPropertySegment navigationPropertySegment = segment as NavigationPropertySegment;
                        if (navigationPropertySegment != null)
                        {
                            if (allNavigationProperties.Contains(navigationPropertySegment.NavigationProperty))
                            {
                                selectedNavigationProperties.Add(navigationPropertySegment.NavigationProperty);
                            }
                            continue;
                        }

                        PropertySegment structuralPropertySegment = segment as PropertySegment;
                        if (structuralPropertySegment != null)
                        {
                            if (allStructuralProperties.Contains(structuralPropertySegment.Property))
                            {
                                selectedStructuralProperties.Add(structuralPropertySegment.Property);
                            }
                            continue;
                        }

                        throw new ODataException(Error.Format(SRResources.SelectionTypeNotSupported, segment.GetType().Name));
                    }

                    WildcardSelectionItem wildCardSelection = selectionItem as WildcardSelectionItem;
                    if (wildCardSelection != null)
                    {
                        selectedStructuralProperties = allStructuralProperties;
                        selectedNavigationProperties = allNavigationProperties;
                        continue;
                    }

                    ContainerQualifiedWildcardSelectionItem wildCardActionSelection = selectionItem as ContainerQualifiedWildcardSelectionItem;
                    if (wildCardActionSelection != null)
                    {
                        IEnumerable<IEdmFunctionImport> actionsInThisContainer = allActions.Where(a => a.Container == wildCardActionSelection.Container);
                        foreach (IEdmFunctionImport action in actionsInThisContainer)
                        {
                            selectedActions.Add(action);
                        }
                        continue;
                    }

                    throw new ODataException(Error.Format(SRResources.SelectionTypeNotSupported, selectionItem.GetType().Name));
                }

                SelectedStructuralProperties = selectedStructuralProperties;
                SelectedNavigationProperties = selectedNavigationProperties;
                SelectedActions = selectedActions;
            }
        }