コード例 #1
0
        /// <summary>
        /// Converts a LinqNewExpression to a Complex Instance
        /// </summary>
        /// <param name="expression">Expression to convert to a ComplexInstance</param>
        /// <returns>Complex Instance</returns>
        internal static ComplexInstance ConvertToComplexInstance(this QueryExpression expression)
        {
            var nullConstantExpression = expression as QueryNullExpression;

            var queryComplexType = (QueryComplexType)expression.ExpressionType;

            if (nullConstantExpression != null)
            {
                return(new ComplexInstance(queryComplexType.ComplexType.FullName, true));
            }

            var structuralExpression = expression as LinqNewInstanceExpression;
            var newComplexInstance   = new ComplexInstance(queryComplexType.ComplexType.FullName, false);

            ExceptionUtilities.Assert(structuralExpression.MemberNames.Count == structuralExpression.Members.Count, "MemberNames and Members count are not equal");

            for (int i = 0; i < structuralExpression.MemberNames.Count; i++)
            {
                string memberName       = structuralExpression.MemberNames[i];
                var    memberExpression = structuralExpression.Members[i];
                var    memberProperty   = queryComplexType.ComplexType.Properties.Single(p => p.Name == memberName);

                var complexDataType    = memberProperty.PropertyType as ComplexDataType;
                var collectionDataType = memberProperty.PropertyType as CollectionDataType;

                if (complexDataType != null)
                {
                    var childComplexInstance = memberExpression.ConvertToComplexInstance();
                    var complexProperty      = new ComplexProperty()
                    {
                        Name = memberName, Value = childComplexInstance
                    };
                    newComplexInstance.Add(complexProperty);
                }
                else if (collectionDataType != null)
                {
                    var collectionPropertyType = memberProperty.PropertyType as CollectionDataType;
                    var convertedValue         = memberExpression.ConvertToMultiValue(collectionPropertyType.ElementDataType);
                    if (collectionPropertyType.ElementDataType is ComplexDataType)
                    {
                        newComplexInstance.Add(new ComplexMultiValueProperty(memberName, convertedValue as ComplexMultiValue));
                    }
                    else
                    {
                        var primitiveDataType = collectionPropertyType.ElementDataType as PrimitiveDataType;
                        ExceptionUtilities.CheckObjectNotNull(primitiveDataType, "Not a primitiveDataType '{0}'", collectionPropertyType.ElementDataType);
                        newComplexInstance.Add(new PrimitiveMultiValueProperty(memberName, convertedValue as PrimitiveMultiValue));
                    }
                }
                else
                {
                    var primitiveDataType = memberProperty.PropertyType as PrimitiveDataType;
                    ExceptionUtilities.CheckObjectNotNull(primitiveDataType, "Expected a PrimitiveDataType");
                    var primitiveValue = memberExpression.ConvertToPrimitiveValue(primitiveDataType);
                    newComplexInstance.Add(new PrimitiveProperty(memberName, primitiveDataType.GetEdmTypeName(), primitiveValue.ClrValue));
                }
            }

            return(newComplexInstance);
        }
コード例 #2
0
        private void PopulatePropertiesFromPaths(ComplexInstance instance, IEnumerable <MemberProperty> properties, string propertyPath, IEnumerable <NamedValue> namedValues)
        {
            ExceptionUtilities.CheckArgumentNotNull(instance, "instance");
            ExceptionUtilities.CheckArgumentNotNull(properties, "properties");
            ExceptionUtilities.CheckArgumentNotNull(namedValues, "namedValues");

            foreach (MemberProperty property in properties)
            {
                string childPropertyPath = property.Name;
                if (propertyPath != null)
                {
                    childPropertyPath = propertyPath + "." + property.Name;
                }

                CollectionDataType collectionDataType = property.PropertyType as CollectionDataType;
                PrimitiveDataType  primitiveDataType  = property.PropertyType as PrimitiveDataType;
                if (primitiveDataType != null)
                {
                    NamedValue memberPropertyNamedValue = namedValues.SingleOrDefault(nv => nv.Name == childPropertyPath);
                    if (memberPropertyNamedValue != null)
                    {
                        instance.Add(this.PrimitiveProperty(property, memberPropertyNamedValue.Value));
                    }
                }
                else if (collectionDataType != null)
                {
                    IEnumerable <NamedValue> bagNamedValues = namedValues.Where(nv => nv.Name.StartsWith(childPropertyPath + ".", StringComparison.Ordinal)).ToList();
                    if (bagNamedValues.Count() > 0)
                    {
                        this.PopulateMultiValuePropertyFromPaths(instance, property, collectionDataType.ElementDataType, childPropertyPath, bagNamedValues);
                    }
                    else
                    {
                        this.PopulateCollectionPropertyWithNullOrEmpty(instance, property, childPropertyPath, namedValues);
                    }
                }
                else
                {
                    var complexDataType = property.PropertyType as ComplexDataType;
                    ExceptionUtilities.CheckObjectNotNull(complexDataType, "Property '{0}' was not primitive, a collection, or complex", property.Name);

                    IEnumerable <NamedValue> complexInstanceNamedValues = namedValues.Where(nv => nv.Name.StartsWith(childPropertyPath + ".", StringComparison.Ordinal)).ToList();
                    if (complexInstanceNamedValues.Count() > 0)
                    {
                        PropertyInstance memberPropertyInstance = this.ComplexProperty(property, childPropertyPath, complexInstanceNamedValues);
                        instance.Add(memberPropertyInstance);
                    }
                    else
                    {
                        // Check for null case
                        IEnumerable <NamedValue> exactMatches = namedValues.Where(nv => nv.Name == childPropertyPath).ToList();
                        ExceptionUtilities.Assert(exactMatches.Count() < 2, "Should only find at most one property path {0} when looking for null value", childPropertyPath);
                        if (exactMatches.Count() == 1)
                        {
                            instance.Add(new ComplexProperty(property.Name, new ComplexInstance(complexDataType.Definition.FullName, true)));
                        }
                    }
                }
            }
        }
コード例 #3
0
        private void PopulatePropertiesFromObject(ComplexInstance instance, IEnumerable <MemberProperty> properties, object anonymous)
        {
            ExceptionUtilities.CheckArgumentNotNull(instance, "instance");
            ExceptionUtilities.CheckArgumentNotNull(properties, "properties");
            ExceptionUtilities.CheckArgumentNotNull(anonymous, "anonymous");

            Type anonymousType = anonymous.GetType();

            foreach (PropertyInfo info in anonymousType.GetProperties())
            {
                object value = info.GetValue(anonymous, null);

                MemberProperty property = properties.SingleOrDefault(p => p.Name == info.Name);
                if (property == null)
                {
                    instance.Add(this.DynamicProperty(info.Name, info.PropertyType, value));
                }
                else if (property.PropertyType is ComplexDataType)
                {
                    instance.Add(this.ComplexProperty(property, value));
                }
                else if (property.PropertyType is CollectionDataType)
                {
                    instance.Add(this.MultiValueProperty(property, value));
                }
                else
                {
                    instance.Add(this.PrimitiveProperty(property, value));
                }
            }
        }
コード例 #4
0
        /// <summary>
        /// Converts a queryExpression to a payload where applicable, returns null if not required
        /// </summary>
        /// <param name="expression">Expression to convert</param>
        /// <returns>OData Payload</returns>
        public ODataPayloadElement ComputePayload(QueryExpression expression)
        {
            LinqToAstoriaProcedureExpressionLocatorVisitor visitor = new LinqToAstoriaProcedureExpressionLocatorVisitor();
            var procedureExpression = visitor.FindProcedure(expression);

            if (procedureExpression == null)
            {
                return(null);
            }

            var actionAnnotation = procedureExpression.Function.Annotations.OfType <ServiceOperationAnnotation>().SingleOrDefault();

            ExceptionUtilities.CheckObjectNotNull(actionAnnotation, "Should have an action annotation");
            ExceptionUtilities.Assert(procedureExpression.Function.IsAction(), "Visitor did not find a procedure");

            var nonboundArguments = procedureExpression.GetNonBoundFunctionArgments();

            var parameterKeyValues = procedureExpression.Function.ConvertActionArgumentsToTypedValues(actionAnnotation, nonboundArguments);

            var complexInstance = new ComplexInstance(null, false);

            foreach (var parameterKeyValuePair in parameterKeyValues)
            {
                var parameterPrimitiveValue = parameterKeyValuePair.Value as PrimitiveValue;
                var primitiveMultiValue     = parameterKeyValuePair.Value as PrimitiveMultiValue;
                var complexMultiValue       = parameterKeyValuePair.Value as ComplexMultiValue;
                if (parameterPrimitiveValue != null)
                {
                    complexInstance.Add(new PrimitiveProperty(parameterKeyValuePair.Key, parameterPrimitiveValue.FullTypeName, parameterPrimitiveValue.ClrValue));
                }
                else if (primitiveMultiValue != null)
                {
                    complexInstance.Add(new PrimitiveMultiValueProperty(parameterKeyValuePair.Key, primitiveMultiValue));
                }
                else if (complexMultiValue != null)
                {
                    complexInstance.Add(new ComplexMultiValueProperty(parameterKeyValuePair.Key, complexMultiValue));
                }
                else
                {
                    var parameterComplexInstance = parameterKeyValuePair.Value as ComplexInstance;
                    ExceptionUtilities.CheckObjectNotNull(parameterComplexInstance, "Unsupported type");
                    complexInstance.Add(new ComplexProperty(parameterKeyValuePair.Key, parameterComplexInstance));
                }
            }

            return(complexInstance);
        }
コード例 #5
0
        private void PopulateComplexMultiValuePropertyFromPaths(ComplexInstance instance, MemberProperty memberProperty, string propertyPath, IEnumerable <NamedValue> namedValues, ComplexDataType complexTypeElementDataType)
        {
            int  i         = 0;
            bool completed = false;

            var complexCollection = new ComplexMultiValueProperty(memberProperty.Name, new ComplexMultiValue(complexTypeElementDataType.BuildMultiValueTypeName(), false));

            while (!completed)
            {
                IEnumerable <NamedValue> complexInstanceNamedValues = namedValues.Where(pp => pp.Name.StartsWith(propertyPath + "." + i + ".", StringComparison.Ordinal)).ToList();
                if (complexInstanceNamedValues.Count() == 0)
                {
                    completed = true;
                }
                else
                {
                    ComplexInstance complexInstance = this.ComplexInstance(complexTypeElementDataType.Definition, propertyPath + "." + i, complexInstanceNamedValues);
                    complexCollection.Value.Add(complexInstance);
                }

                i++;
            }

            if (i > 1)
            {
                instance.Add(complexCollection);
            }
        }
コード例 #6
0
        private void PopulatePrimitiveBagPropertyFromPaths(ComplexInstance instance, MemberProperty memberProperty, string propertyPath, IEnumerable <NamedValue> namedValues, PrimitiveDataType primitiveElementDataType)
        {
            int  i         = 0;
            bool completed = false;

            var primitiveCollection = new PrimitiveMultiValue(primitiveElementDataType.BuildMultiValueTypeName(), false);

            while (!completed)
            {
                IEnumerable <NamedValue> primitiveItemNamedValues = namedValues.Where(pp => pp.Name == propertyPath + "." + i).ToList();
                if (primitiveItemNamedValues.Count() == 0)
                {
                    completed = true;
                }
                else
                {
                    ExceptionUtilities.Assert(primitiveItemNamedValues.Count() < 2, "Should not get more than one value for a primitive Bag item for path '{0}'", propertyPath + "." + i);
                    var value = primitiveItemNamedValues.Single();

                    // Do something with the value
                    primitiveCollection.Add(PrimitiveValue(primitiveElementDataType, value.Value));
                }

                i++;
            }

            if (i > 1)
            {
                instance.Add(new PrimitiveMultiValueProperty(memberProperty.Name, primitiveCollection));
            }
        }
コード例 #7
0
        /// <summary>
        /// Deserialize the element as a complex instance
        /// </summary>
        /// <param name="element">The xml representing a complex instance</param>
        /// <returns>The deserialized complex instance</returns>
        private ComplexInstance DeserializeComplexInstance(XElement element)
        {
            ComplexInstance instance = new ComplexInstance();

            // get the type
            XAttribute type = element.Attribute(MetadataType);

            if (type != null)
            {
                instance.FullTypeName = type.Value;
            }

            // check for the null attribute
            XAttribute isNull = element.Attribute(MetadataNull);

            if (isNull != null)
            {
                instance.IsNull = bool.Parse(isNull.Value);
            }
            else if (element.HasElements)
            {
                instance.IsNull = false;
            }

            // get the properties
            foreach (XElement subElement in element.Elements())
            {
                instance.Add(this.DeserializeProperty(subElement));
            }

            return(instance);
        }
コード例 #8
0
            /// <summary>
            /// Because the test deserializer used to parse the actual payload will not have metadata, we fix it up here.
            /// Note: this should probably move to happen just before comparison, rather than when generating expectations.
            /// </summary>
            /// <param name="payloadElement">The payload element</param>
            private void SortAndNormalizeProperties(ComplexInstance payloadElement)
            {
                var sortedProperties = payloadElement.Properties.OrderBy(p => p.Name).ToList();

                foreach (var p in sortedProperties)
                {
                    var property = p;
                    payloadElement.Remove(property);

                    // If we have a primitive property with null value, we write a type name for the null value
                    // in V1 and V2. If not type name is available or we are in V3, we don't do that and thus expect a null property instance.
                    var primitiveProperty = property as PrimitiveProperty;
                    if (primitiveProperty != null && primitiveProperty.Value.IsNull &&
                        (this.dsv >= DataServiceProtocolVersion.V4 || string.IsNullOrEmpty(primitiveProperty.Value.FullTypeName)))
                    {
                        property = new NullPropertyInstance(property.Name, null).WithAnnotations(property.Annotations);
                    }

                    var complexProperty = property as ComplexProperty;
                    if (complexProperty != null && complexProperty.Value.IsNull)
                    {
                        property = new NullPropertyInstance(property.Name, complexProperty.Value.FullTypeName).WithAnnotations(property.Annotations);
                    }

                    var complexCollectionProperty = property as ComplexMultiValueProperty;
                    if (complexCollectionProperty != null && complexCollectionProperty.Value.Count == 0 && complexCollectionProperty.Value.FullTypeName == null)
                    {
                        property = new PrimitiveProperty(complexCollectionProperty.Name, complexCollectionProperty.Value.FullTypeName, string.Empty);
                    }

                    payloadElement.Add(property);
                }
            }
コード例 #9
0
ファイル: PayloadGenerator.cs プロジェクト: zhonli/odata.net
        private PropertyInstance BuildProperty(IEdmProperty property)
        {
            if (property.Type.IsCollection())
            {
                var type = (IEdmCollectionType)property.Type.Definition;
                if (type.ElementType.IsComplex())
                {
                    var complex = new ComplexInstance(property.Type.FullName(), false).WithTypeAnnotation(type.ElementType.Definition);
                    foreach (var prop in ((IEdmComplexType)type.ElementType.Definition).StructuralProperties())
                    {
                        complex.Add(this.BuildProperty(prop));
                    }

                    return(new ComplexMultiValueProperty(property.Name,
                                                         new ComplexMultiValue(property.Type.FullName(), false, complex)).WithTypeAnnotation(type));
                }

                return(new PrimitiveMultiValueProperty(property.Name,
                                                       new PrimitiveMultiValue(property.Type.FullName(), false,
                                                                               this.GetValue((IEdmPrimitiveTypeReference)type.ElementType))).WithTypeAnnotation(property.Type));
            }

            if (property.IsComplex())
            {
                var complex = new ComplexInstance(property.Type.FullName(), false);
                foreach (var prop in ((IEdmComplexType)property.Type.Definition).StructuralProperties())
                {
                    complex.Add(this.BuildProperty(prop));
                }

                return(new ComplexProperty(property.Name, complex).WithTypeAnnotation(property.Type));
            }

            return(new PrimitiveProperty((property.Name), this.GetValue((IEdmPrimitiveTypeReference)property.Type)).WithTypeAnnotation(property.Type));
        }
コード例 #10
0
        /// <summary>
        /// Converts a queryExpression to a payload where applicable, returns null if not required
        /// </summary>
        /// <param name="expression">Expression to convert</param>
        /// <returns>OData Payload</returns>
        public ODataPayloadElement ComputePayload(QueryExpression expression)
        {
            LinqToAstoriaProcedureExpressionLocatorVisitor visitor = new LinqToAstoriaProcedureExpressionLocatorVisitor();
            var procedureExpression = visitor.FindProcedure(expression);

            if (procedureExpression == null)
            {
                return null;
            }

            var actionAnnotation = procedureExpression.Function.Annotations.OfType<ServiceOperationAnnotation>().SingleOrDefault();
            
            ExceptionUtilities.CheckObjectNotNull(actionAnnotation, "Should have an action annotation");
            ExceptionUtilities.Assert(procedureExpression.Function.IsAction(), "Visitor did not find a procedure");

            var nonboundArguments = procedureExpression.GetNonBoundFunctionArgments();

            var parameterKeyValues = procedureExpression.Function.ConvertActionArgumentsToTypedValues(actionAnnotation, nonboundArguments);

            var complexInstance = new ComplexInstance(null, false);
            foreach (var parameterKeyValuePair in parameterKeyValues)
            {
                var parameterPrimitiveValue = parameterKeyValuePair.Value as PrimitiveValue;
                var primitiveMultiValue = parameterKeyValuePair.Value as PrimitiveMultiValue;
                var complexMultiValue = parameterKeyValuePair.Value as ComplexMultiValue; 
                if (parameterPrimitiveValue != null)
                {
                    complexInstance.Add(new PrimitiveProperty(parameterKeyValuePair.Key, parameterPrimitiveValue.FullTypeName, parameterPrimitiveValue.ClrValue));
                }
                else if (primitiveMultiValue != null)
                {
                    complexInstance.Add(new PrimitiveMultiValueProperty(parameterKeyValuePair.Key, primitiveMultiValue));
                }
                else if (complexMultiValue != null)
                {
                    complexInstance.Add(new ComplexMultiValueProperty(parameterKeyValuePair.Key, complexMultiValue));
                }
                else
                {
                    var parameterComplexInstance = parameterKeyValuePair.Value as ComplexInstance;
                    ExceptionUtilities.CheckObjectNotNull(parameterComplexInstance, "Unsupported type");
                    complexInstance.Add(new ComplexProperty(parameterKeyValuePair.Key, parameterComplexInstance));
                }
            }

            return complexInstance;
        }
コード例 #11
0
        private void PopulateCollectionPropertyWithNullOrEmpty(ComplexInstance instance, MemberProperty memberProperty, string propertyPath, IEnumerable <NamedValue> namedValues)
        {
            IEnumerable <NamedValue> exactMatches = namedValues.Where(nv => nv.Name == propertyPath).ToList();

            ExceptionUtilities.Assert(exactMatches.Count() < 2, "Should only find at most one property path {0} when looking for null value", propertyPath);
            if (exactMatches.Count() == 1)
            {
                instance.Add(this.MultiValuePropertyEmptyOrNull(memberProperty, exactMatches.Single().Value));
            }
        }
コード例 #12
0
            /// <summary>
            /// Visits a collection of parameters.
            /// </summary>
            /// <param name="parameters">The parameters to visit.</param>
            protected override ODataPayloadElement VisitParameters(ODataParameters parameters)
            {
                ExceptionUtilities.CheckArgumentNotNull(parameters, "parameters");
                ComplexInstance result = new ComplexInstance();

                result.IsNull = parameters.Count == 0;
                foreach (var parameter in parameters)
                {
                    if (parameter.Value == null)
                    {
                        result.Add(new PrimitiveProperty(parameter.Key, null, null));
                        continue;
                    }

                    ODataCollectionStart odataCollectionStart = parameter.Value as ODataCollectionStart;

                    if (odataCollectionStart != null)
                    {
                        ODataCollectionItemsObjectModelAnnotation annotation = odataCollectionStart.GetAnnotation <ODataCollectionItemsObjectModelAnnotation>();

                        PrimitiveMultiValue primitiveCollection = PayloadBuilder.PrimitiveMultiValue();
                        foreach (var value in annotation)
                        {
                            primitiveCollection.Item(value);
                        }

                        PrimitiveMultiValueProperty primitiveCollectionProperty = new PrimitiveMultiValueProperty(parameter.Key, primitiveCollection);
                        result.Add(primitiveCollectionProperty);
                    }
                    else
                    {
                        result.Add(new PrimitiveProperty(parameter.Key, null, PayloadBuilder.PrimitiveValue(parameter.Value).ClrValue));
                    }
                }

                return(result);
            }
コード例 #13
0
            /// <summary>
            /// Visits a resource value item.
            /// </summary>
            /// <param name="resourceValue">The resource value to visit.</param>
            protected override ODataPayloadElement VisitResourceValue(ODataResourceValue resourceValue)
            {
                if (resourceValue == null)
                {
                    return(new ComplexInstance(null, true));
                }
                else
                {
                    ComplexInstance complexElement = new ComplexInstance(resourceValue.TypeName, false);
                    foreach (ODataProperty childProperty in resourceValue.Properties)
                    {
                        complexElement.Add((PropertyInstance)this.Visit(childProperty));
                    }

                    this.ConvertSerializationTypeNameAnnotation(resourceValue, complexElement);

                    return(complexElement);
                }
            }
コード例 #14
0
        private bool TryGetComplexInstance(JsonObject jsonObject, out ODataPayloadElement elem)
        {
            string          typeName = this.GetMetadataPropertyValue(jsonObject, TypeFieldName);
            ComplexInstance complex  = new ComplexInstance(typeName, false);

            elem = null;

            foreach (JsonProperty prop in jsonObject.Properties)
            {
                // Just parse the object properties. Skip properties like "__metadata", "Count" and "Next"
                if (prop.Name != MetadataFieldName)
                {
                    complex.Add(this.ConvertProperty(prop) as PropertyInstance);
                }
            }

            elem = complex;
            return(elem != null);
        }
        /// <summary>
        /// Converts a LinqNewExpression to a Complex Instance
        /// </summary>
        /// <param name="expression">Expression to convert to a ComplexInstance</param>
        /// <returns>Complex Instance</returns>
        internal static ComplexInstance ConvertToComplexInstance(this QueryExpression expression)
        {
            var nullConstantExpression = expression as QueryNullExpression;

            var queryComplexType = (QueryComplexType)expression.ExpressionType;
            if (nullConstantExpression != null)
            {
                return new ComplexInstance(queryComplexType.ComplexType.FullName, true);
            }

            var structuralExpression = expression as LinqNewInstanceExpression;
            var newComplexInstance = new ComplexInstance(queryComplexType.ComplexType.FullName, false);
            ExceptionUtilities.Assert(structuralExpression.MemberNames.Count == structuralExpression.Members.Count, "MemberNames and Members count are not equal");

            for (int i = 0; i < structuralExpression.MemberNames.Count; i++)
            {
                string memberName = structuralExpression.MemberNames[i];
                var memberExpression = structuralExpression.Members[i];
                var memberProperty = queryComplexType.ComplexType.Properties.Single(p => p.Name == memberName);

                var complexDataType = memberProperty.PropertyType as ComplexDataType;
                var collectionDataType = memberProperty.PropertyType as CollectionDataType;

                if (complexDataType != null)
                {
                    var childComplexInstance = memberExpression.ConvertToComplexInstance();
                    var complexProperty = new ComplexProperty() { Name = memberName, Value = childComplexInstance };
                    newComplexInstance.Add(complexProperty);
                }
                else if (collectionDataType != null)
                {
                    var collectionPropertyType = memberProperty.PropertyType as CollectionDataType;
                    var convertedValue = memberExpression.ConvertToMultiValue(collectionPropertyType.ElementDataType);
                    if (collectionPropertyType.ElementDataType is ComplexDataType)
                    {
                        newComplexInstance.Add(new ComplexMultiValueProperty(memberName, convertedValue as ComplexMultiValue));
                    }
                    else
                    {
                        var primitiveDataType = collectionPropertyType.ElementDataType as PrimitiveDataType;
                        ExceptionUtilities.CheckObjectNotNull(primitiveDataType, "Not a primitiveDataType '{0}'", collectionPropertyType.ElementDataType);
                        newComplexInstance.Add(new PrimitiveMultiValueProperty(memberName, convertedValue as PrimitiveMultiValue));
                    }
                }
                else
                {
                    var primitiveDataType = memberProperty.PropertyType as PrimitiveDataType;
                    ExceptionUtilities.CheckObjectNotNull(primitiveDataType, "Expected a PrimitiveDataType");
                    var primitiveValue = memberExpression.ConvertToPrimitiveValue(primitiveDataType);
                    newComplexInstance.Add(new PrimitiveProperty(memberName, primitiveDataType.GetEdmTypeName(), primitiveValue.ClrValue));
                }
            }

            return newComplexInstance;
        }
コード例 #16
0
            /// <summary>
            /// Because the test deserializer used to parse the actual payload will not have metadata, we fix it up here.
            /// Note: this should probably move to happen just before comparison, rather than when generating expectations.
            /// </summary>
            /// <param name="payloadElement">The payload element</param>
            private void SortAndNormalizeProperties(ComplexInstance payloadElement)
            {
                var sortedProperties = payloadElement.Properties.OrderBy(p => p.Name).ToList();
                foreach (var p in sortedProperties)
                {
                    var property = p;
                    payloadElement.Remove(property);

                    // If we have a primitive property with null value, we write a type name for the null value
                    // in V1 and V2. If not type name is available or we are in V3, we don't do that and thus expect a null property instance.
                    var primitiveProperty = property as PrimitiveProperty;
                    if (primitiveProperty != null && primitiveProperty.Value.IsNull && 
                        (this.dsv >= DataServiceProtocolVersion.V4 || string.IsNullOrEmpty(primitiveProperty.Value.FullTypeName)))
                    {
                        property = new NullPropertyInstance(property.Name, null).WithAnnotations(property.Annotations);
                    }

                    var complexProperty = property as ComplexProperty;
                    if (complexProperty != null && complexProperty.Value.IsNull)
                    {
                        property = new NullPropertyInstance(property.Name, complexProperty.Value.FullTypeName).WithAnnotations(property.Annotations);
                    }

                    var complexCollectionProperty = property as ComplexMultiValueProperty;
                    if (complexCollectionProperty != null && complexCollectionProperty.Value.Count == 0 && complexCollectionProperty.Value.FullTypeName == null)
                    {
                        property = new PrimitiveProperty(complexCollectionProperty.Name, complexCollectionProperty.Value.FullTypeName, string.Empty);
                    }

                    payloadElement.Add(property);
                }
            }
コード例 #17
0
        private void PopulatePropertiesFromObject(ComplexInstance instance, IEnumerable<MemberProperty> properties, object anonymous)
        {
            ExceptionUtilities.CheckArgumentNotNull(instance, "instance");
            ExceptionUtilities.CheckArgumentNotNull(properties, "properties");
            ExceptionUtilities.CheckArgumentNotNull(anonymous, "anonymous");

            Type anonymousType = anonymous.GetType();
            foreach (PropertyInfo info in anonymousType.GetProperties())
            {
                object value = info.GetValue(anonymous, null);

                MemberProperty property = properties.SingleOrDefault(p => p.Name == info.Name);
                if (property == null)
                {
                    instance.Add(this.DynamicProperty(info.Name, info.PropertyType, value));
                }
                else if (property.PropertyType is ComplexDataType)
                {
                    instance.Add(this.ComplexProperty(property, value));
                }
                else if (property.PropertyType is CollectionDataType)
                {
                    instance.Add(this.MultiValueProperty(property, value));
                }
                else
                {
                    instance.Add(this.PrimitiveProperty(property, value));
                }
            }
        }
コード例 #18
0
        private void PopulateComplexMultiValuePropertyFromPaths(ComplexInstance instance, MemberProperty memberProperty, string propertyPath, IEnumerable<NamedValue> namedValues, ComplexDataType complexTypeElementDataType)
        {
            int i = 0;
            bool completed = false;

            var complexCollection = new ComplexMultiValueProperty(memberProperty.Name, new ComplexMultiValue(complexTypeElementDataType.BuildMultiValueTypeName(), false));
            while (!completed)
            {
                IEnumerable<NamedValue> complexInstanceNamedValues = namedValues.Where(pp => pp.Name.StartsWith(propertyPath + "." + i + ".", StringComparison.Ordinal)).ToList();
                if (complexInstanceNamedValues.Count() == 0)
                {
                    completed = true;
                }
                else
                {
                    ComplexInstance complexInstance = this.ComplexInstance(complexTypeElementDataType.Definition, propertyPath + "." + i, complexInstanceNamedValues);
                    complexCollection.Value.Add(complexInstance);
                }

                i++;
            }

            if (i > 1)
            {
                instance.Add(complexCollection);
            }
        }
コード例 #19
0
        private void PopulatePrimitiveBagPropertyFromPaths(ComplexInstance instance, MemberProperty memberProperty, string propertyPath, IEnumerable<NamedValue> namedValues, PrimitiveDataType primitiveElementDataType)
        {
            int i = 0;
            bool completed = false;

            var primitiveCollection = new PrimitiveMultiValue(primitiveElementDataType.BuildMultiValueTypeName(), false);
            while (!completed)
            {
                IEnumerable<NamedValue> primitiveItemNamedValues = namedValues.Where(pp => pp.Name == propertyPath + "." + i).ToList();
                if (primitiveItemNamedValues.Count() == 0)
                {
                    completed = true;
                }
                else
                {
                    ExceptionUtilities.Assert(primitiveItemNamedValues.Count() < 2, "Should not get more than one value for a primitive Bag item for path '{0}'", propertyPath + "." + i);
                    var value = primitiveItemNamedValues.Single();

                    // Do something with the value
                    primitiveCollection.Add(PrimitiveValue(primitiveElementDataType, value.Value));
                }

                i++;
            }

            if (i > 1)
            {
                instance.Add(new PrimitiveMultiValueProperty(memberProperty.Name, primitiveCollection));
            }
        }
コード例 #20
0
        /// <summary>
        /// Deserialize the element as a complex instance
        /// </summary>
        /// <param name="element">The xml representing a complex instance</param>
        /// <returns>The deserialized complex instance</returns>
        private ComplexInstance DeserializeComplexInstance(XElement element)
        {
            ComplexInstance instance = new ComplexInstance();

            // get the type
            XAttribute type = element.Attribute(MetadataType);
            if (type != null)
            {
                instance.FullTypeName = type.Value;
            }

            // check for the null attribute
            XAttribute isNull = element.Attribute(MetadataNull);
            if (isNull != null)
            {
                instance.IsNull = bool.Parse(isNull.Value);
            }
            else if (element.HasElements)
            {
                instance.IsNull = false;
            }

            // get the properties
            foreach (XElement subElement in element.Elements())
            {
                instance.Add(this.DeserializeProperty(subElement));
            }

            return instance;
        }
コード例 #21
0
 private void PopulateCollectionPropertyWithNullOrEmpty(ComplexInstance instance, MemberProperty memberProperty, string propertyPath, IEnumerable<NamedValue> namedValues)
 {
     IEnumerable<NamedValue> exactMatches = namedValues.Where(nv => nv.Name == propertyPath).ToList();
     ExceptionUtilities.Assert(exactMatches.Count() < 2, "Should only find at most one property path {0} when looking for null value", propertyPath);
     if (exactMatches.Count() == 1)
     {
         instance.Add(this.MultiValuePropertyEmptyOrNull(memberProperty, exactMatches.Single().Value));
     }
 }
コード例 #22
0
        private void PopulatePropertiesFromPaths(ComplexInstance instance, IEnumerable<MemberProperty> properties, string propertyPath, IEnumerable<NamedValue> namedValues)
        {
            ExceptionUtilities.CheckArgumentNotNull(instance, "instance");
            ExceptionUtilities.CheckArgumentNotNull(properties, "properties");
            ExceptionUtilities.CheckArgumentNotNull(namedValues, "namedValues");

            foreach (MemberProperty property in properties)
            {
                string childPropertyPath = property.Name;
                if (propertyPath != null)
                {
                    childPropertyPath = propertyPath + "." + property.Name;
                }

                CollectionDataType collectionDataType = property.PropertyType as CollectionDataType;
                PrimitiveDataType primitiveDataType = property.PropertyType as PrimitiveDataType;
                if (primitiveDataType != null)
                {
                    NamedValue memberPropertyNamedValue = namedValues.SingleOrDefault(nv => nv.Name == childPropertyPath);
                    if (memberPropertyNamedValue != null)
                    {
                        instance.Add(this.PrimitiveProperty(property, memberPropertyNamedValue.Value));
                    }
                }
                else if (collectionDataType != null)
                {
                    IEnumerable<NamedValue> bagNamedValues = namedValues.Where(nv => nv.Name.StartsWith(childPropertyPath + ".", StringComparison.Ordinal)).ToList();
                    if (bagNamedValues.Count() > 0)
                    {
                        this.PopulateMultiValuePropertyFromPaths(instance, property, collectionDataType.ElementDataType, childPropertyPath, bagNamedValues);
                    }
                    else
                    {
                        this.PopulateCollectionPropertyWithNullOrEmpty(instance, property, childPropertyPath, namedValues);
                    }
                }
                else
                {
                    var complexDataType = property.PropertyType as ComplexDataType;
                    ExceptionUtilities.CheckObjectNotNull(complexDataType, "Property '{0}' was not primitive, a collection, or complex", property.Name);

                    IEnumerable<NamedValue> complexInstanceNamedValues = namedValues.Where(nv => nv.Name.StartsWith(childPropertyPath + ".", StringComparison.Ordinal)).ToList();
                    if (complexInstanceNamedValues.Count() > 0)
                    {
                        PropertyInstance memberPropertyInstance = this.ComplexProperty(property, childPropertyPath, complexInstanceNamedValues);
                        instance.Add(memberPropertyInstance);
                    }
                    else
                    {
                        // Check for null case
                        IEnumerable<NamedValue> exactMatches = namedValues.Where(nv => nv.Name == childPropertyPath).ToList();
                        ExceptionUtilities.Assert(exactMatches.Count() < 2, "Should only find at most one property path {0} when looking for null value", childPropertyPath);
                        if (exactMatches.Count() == 1)
                        {
                            instance.Add(new ComplexProperty(property.Name, new ComplexInstance(complexDataType.Definition.FullName, true)));
                        }
                    }
                }
            }
        }
コード例 #23
0
            /// <summary>
            /// Visits a collection of parameters.
            /// </summary>
            /// <param name="parameters">The parameters to visit.</param>
            protected override ODataPayloadElement VisitParameters(ODataParameters parameters)
            {
                ExceptionUtilities.CheckArgumentNotNull(parameters, "parameters");
                ComplexInstance result = new ComplexInstance();

                result.IsNull = parameters.Count == 0;
                foreach (var parameter in parameters)
                {
                    if (parameter.Value == null)
                    {
                        result.Add(new PrimitiveProperty(parameter.Key, null, null));
                        continue;
                    }

                    ODataComplexValue    odataComplexValue    = parameter.Value as ODataComplexValue;
                    ODataCollectionStart odataCollectionStart = parameter.Value as ODataCollectionStart;

                    if (odataCollectionStart != null)
                    {
                        ODataCollectionItemsObjectModelAnnotation annotation = odataCollectionStart.GetAnnotation <ODataCollectionItemsObjectModelAnnotation>();
                        if (annotation.OfType <ODataComplexValue>().FirstOrDefault() != null)
                        {
                            ComplexMultiValue complexCollection = PayloadBuilder.ComplexMultiValue();
                            foreach (var value in annotation)
                            {
                                complexCollection.Item(this.VisitComplexValue(value as ODataComplexValue) as ComplexInstance);
                            }

                            ComplexMultiValueProperty complexCollectionProperty = new ComplexMultiValueProperty(parameter.Key, complexCollection);
                            result.Add(complexCollectionProperty);
                        }
                        else
                        {
                            PrimitiveMultiValue primitiveCollection = PayloadBuilder.PrimitiveMultiValue();
                            foreach (var value in annotation)
                            {
                                primitiveCollection.Item(value);
                            }

                            PrimitiveMultiValueProperty primitiveCollectionProperty = new PrimitiveMultiValueProperty(parameter.Key, primitiveCollection);
                            result.Add(primitiveCollectionProperty);
                        }
                    }
                    else if (odataComplexValue != null)
                    {
                        ComplexInstance complexInstance = PayloadBuilder.ComplexValue(odataComplexValue.TypeName);
                        complexInstance.IsNull = false;
                        foreach (ODataProperty odataProperty in odataComplexValue.Properties)
                        {
                            complexInstance.Property(odataProperty.Name, this.Visit(odataProperty.Value));
                        }

                        result.Add(new ComplexProperty(parameter.Key, complexInstance));
                    }
                    else
                    {
                        result.Add(new PrimitiveProperty(parameter.Key, null, PayloadBuilder.PrimitiveValue(parameter.Value).ClrValue));
                    }
                }

                return(result);
            }
コード例 #24
0
        private static ODataPayloadElement CreatePayloadElement(IEdmModel model, ODataPayloadKind payloadKind, ReaderTestConfiguration testConfig)
        {
            IEdmEntitySet          citySet              = model.EntityContainer.FindEntitySet("Cities");
            IEdmEntityType         cityType             = model.EntityTypes().Single(e => e.Name == "CityType");
            IEdmProperty           cityNameProperty     = cityType.Properties().Single(e => e.Name == "Name");
            IEdmNavigationProperty policeStationNavProp = cityType.NavigationProperties().Single(e => e.Name == "PoliceStation");
            IEdmOperationImport    primitiveCollectionResultOperation = model.EntityContainer.FindOperationImports("PrimitiveCollectionResultOperation").Single();
            IEdmOperationImport    serviceOp1 = model.EntityContainer.FindOperationImports("ServiceOperation1").Single();

            bool isRequest          = testConfig.IsRequest;
            bool isJsonLightRequest = isRequest && testConfig.Format == ODataFormat.Json;

            switch (payloadKind)
            {
            case ODataPayloadKind.Feed:
            {
                return(PayloadBuilder.EntitySet().WithTypeAnnotation(cityType).ExpectedEntityType(cityType, citySet));
            }

            case ODataPayloadKind.Entry:
            {
                return(PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).WithTypeAnnotation(cityType).ExpectedEntityType(cityType, citySet));
            }

            case ODataPayloadKind.Property:
                return(PayloadBuilder.PrimitiveProperty(isJsonLightRequest ? string.Empty : null, "SomeCityValue").ExpectedProperty(cityType, "Name"));

            case ODataPayloadKind.EntityReferenceLink:
                return(PayloadBuilder.DeferredLink("http://odata.org/entityreferencelink").ExpectedNavigationProperty(citySet, cityType, "PoliceStation"));

            case ODataPayloadKind.EntityReferenceLinks:
                return(PayloadBuilder.LinkCollection().Item(PayloadBuilder.DeferredLink("http://odata.org/entityreferencelink")).ExpectedNavigationProperty((EdmEntitySet)citySet, (EdmEntityType)cityType, "CityHall"));

            case ODataPayloadKind.Value:
                return(PayloadBuilder.PrimitiveValue("PrimitiveValue"));

            case ODataPayloadKind.BinaryValue:
                return(PayloadBuilder.PrimitiveValue(new byte[] { 0, 0, 1, 1 }));

            case ODataPayloadKind.Collection:
                return(PayloadBuilder.PrimitiveCollection().CollectionName(null).ExpectedFunctionImport((EdmOperationImport)primitiveCollectionResultOperation));

            case ODataPayloadKind.ServiceDocument:
                Debug.Assert(!isRequest, "Not supported in requests.");
                return(new ServiceDocumentInstance().Workspace(PayloadBuilder.Workspace()));

            case ODataPayloadKind.MetadataDocument:
                Debug.Assert(!isRequest, "Not supported in requests.");
                throw new NotImplementedException();

            case ODataPayloadKind.Error:
                Debug.Assert(!isRequest, "Not supported in requests.");
                return(PayloadBuilder.Error("ErrorCode"));

            case ODataPayloadKind.Parameter:
                // build parameter payload based on model definition
                var parameterPayload           = new ComplexInstance(null, false);
                ODataPayloadElement a          = PayloadBuilder.PrimitiveValue(123).WithTypeAnnotation(EdmCoreModel.Instance.GetInt32(false));
                ODataPayloadElement b          = PayloadBuilder.PrimitiveValue("stringvalue").WithTypeAnnotation(EdmCoreModel.Instance.GetString(false));
                PrimitiveProperty   parametera = new PrimitiveProperty("a", "Edm.Integer", ((PrimitiveValue)a).ClrValue);
                PrimitiveProperty   parameterb = new PrimitiveProperty("b", "Edm.String", ((PrimitiveValue)b).ClrValue);
                parameterPayload.Add(parametera);
                parameterPayload.Add(parameterb);
                parameterPayload.ExpectedFunctionImport((EdmOperationImport)serviceOp1);
                return(parameterPayload);

            case ODataPayloadKind.Unsupported:      // fall through
            default:
                throw new NotSupportedException();
            }
        }
コード例 #25
0
        /// <summary>
        /// Builds a complex instance from the given payloadElements to represent a parameters payload.
        /// </summary>
        /// <param name="payloadElements">Each ODataPayloadElement represents the value for each parameter.</param>
        /// <param name="model">EdmModel instance.</param>
        /// <param name="functionImportName">Name of the function import to add to the model.</param>
        /// <returns></returns>
        private static ComplexInstance PayloadElementsToParameterPayload(ODataPayloadElement[] payloadElements, EdmModel model, string functionImportName)
        {
            EdmOperationImport operationImport = (EdmOperationImport)model.EntityContainer.FindOperationImports(functionImportName).FirstOrDefault();
            EdmOperation       operation       = (EdmOperation)operationImport.Operation;

            var parameterPayload = new ComplexInstance(null, false);

            for (int idx = 0; idx < payloadElements.Length; idx++)
            {
                ODataPayloadElement p           = payloadElements[idx];
                string            parameterName = "p" + idx;
                PropertyInstance  parameter;
                IEdmTypeReference entityModelType = p.GetAnnotation <EntityModelTypeAnnotation>().EdmModelType;
                switch (p.ElementType)
                {
                case ODataPayloadElementType.PrimitiveValue:
                    object         clrValue       = ((PrimitiveValue)p).ClrValue;
                    PrimitiveValue primitiveValue = new PrimitiveValue(clrValue == null ? null : clrValue.GetType().FullName, clrValue);
                    primitiveValue.CopyAnnotation <PrimitiveValue, EntityModelTypeAnnotation>(p);
                    parameter = new PrimitiveProperty(parameterName, primitiveValue);
                    operation.AddParameter(parameterName, MetadataUtils.GetPrimitiveTypeReference(primitiveValue.ClrValue.GetType()));
                    break;

                case ODataPayloadElementType.ComplexInstance:
                    parameter = new ComplexProperty(parameterName, (ComplexInstance)p);
                    operation.AddParameter(parameterName, entityModelType);
                    break;

                case ODataPayloadElementType.PrimitiveMultiValue:
                    PrimitiveMultiValue primitiveMultiValue = (PrimitiveMultiValue)p;
                    if (primitiveMultiValue.Annotations.OfType <JsonCollectionResultWrapperAnnotation>().SingleOrDefault() == null)
                    {
                        primitiveMultiValue.Annotations.Add(new JsonCollectionResultWrapperAnnotation(false));
                    }

                    parameter = new PrimitiveMultiValueProperty(parameterName, primitiveMultiValue);
                    operation.AddParameter(parameterName, entityModelType);
                    break;

                case ODataPayloadElementType.ComplexMultiValue:
                    ComplexMultiValue complexMultiValue = (ComplexMultiValue)p;
                    if (complexMultiValue.Annotations.OfType <JsonCollectionResultWrapperAnnotation>().SingleOrDefault() == null)
                    {
                        complexMultiValue.Annotations.Add(new JsonCollectionResultWrapperAnnotation(false));
                    }

                    parameter = new ComplexMultiValueProperty(parameterName, complexMultiValue);
                    operation.AddParameter(parameterName, entityModelType);
                    break;

                case ODataPayloadElementType.EntityInstance:
                    parameter = new NavigationPropertyInstance(parameterName, (EntityInstance)p);
                    operation.AddParameter(parameterName, entityModelType);
                    break;

                case ODataPayloadElementType.EntitySetInstance:
                    parameter = new NavigationPropertyInstance(parameterName, (EntitySetInstance)p);
                    operation.AddParameter(parameterName, entityModelType);
                    break;

                default:
                    throw new NotSupportedException("PayloadElementsToParameterPayload() is called on unsupported ODataPayloadElement type: " + p.ElementType);
                }

                parameterPayload.Add(parameter);
            }

            parameterPayload.ExpectedFunctionImport(operationImport);
            return(parameterPayload);
        }
コード例 #26
0
        private static ODataPayloadElement CreatePayloadElement(IEdmModel model, ODataPayloadKind payloadKind, ReaderTestConfiguration testConfig)
        {
            IEdmEntitySet citySet = model.EntityContainer.FindEntitySet("Cities");
            IEdmEntityType cityType = model.EntityTypes().Single(e => e.Name == "CityType");
            IEdmProperty cityNameProperty = cityType.Properties().Single(e => e.Name == "Name");
            IEdmNavigationProperty policeStationNavProp = cityType.NavigationProperties().Single(e => e.Name == "PoliceStation");
            IEdmOperationImport primitiveCollectionResultOperation = model.EntityContainer.FindOperationImports("PrimitiveCollectionResultOperation").Single();
            IEdmOperationImport serviceOp1 = model.EntityContainer.FindOperationImports("ServiceOperation1").Single();

            bool isRequest = testConfig.IsRequest;
            bool isJsonLightRequest = isRequest && testConfig.Format == ODataFormat.Json;
            switch (payloadKind)
            {
                case ODataPayloadKind.Feed:
                    {
                        return PayloadBuilder.EntitySet().WithTypeAnnotation(cityType).ExpectedEntityType(cityType, citySet);
                    }
                case ODataPayloadKind.Entry:
                    {
                        return PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).WithTypeAnnotation(cityType).ExpectedEntityType(cityType, citySet);
                    }
                case ODataPayloadKind.Property:
                    return PayloadBuilder.PrimitiveProperty(isJsonLightRequest ? string.Empty : null, "SomeCityValue").ExpectedProperty(cityType, "Name");
                case ODataPayloadKind.EntityReferenceLink:
                    return PayloadBuilder.DeferredLink("http://odata.org/entityreferencelink").ExpectedNavigationProperty(citySet, cityType, "PoliceStation");

                case ODataPayloadKind.EntityReferenceLinks:
                    return PayloadBuilder.LinkCollection().Item(PayloadBuilder.DeferredLink("http://odata.org/entityreferencelink")).ExpectedNavigationProperty((EdmEntitySet)citySet, (EdmEntityType)cityType, "CityHall");

                case ODataPayloadKind.Value:
                    return PayloadBuilder.PrimitiveValue("PrimitiveValue");
                case ODataPayloadKind.BinaryValue:
                    return PayloadBuilder.PrimitiveValue(new byte[] { 0, 0, 1, 1 });
                case ODataPayloadKind.Collection:
                    return PayloadBuilder.PrimitiveCollection().CollectionName(null).ExpectedFunctionImport((EdmOperationImport)primitiveCollectionResultOperation);

                case ODataPayloadKind.ServiceDocument:
                    Debug.Assert(!isRequest, "Not supported in requests.");
                    return new ServiceDocumentInstance().Workspace(PayloadBuilder.Workspace());

                case ODataPayloadKind.MetadataDocument:
                    Debug.Assert(!isRequest, "Not supported in requests.");
                    throw new NotImplementedException();
                case ODataPayloadKind.Error:
                    Debug.Assert(!isRequest, "Not supported in requests.");
                    return PayloadBuilder.Error("ErrorCode");

                case ODataPayloadKind.Parameter:
                    // build parameter payload based on model definition
                    var parameterPayload = new ComplexInstance(null, false);
                    ODataPayloadElement a = PayloadBuilder.PrimitiveValue(123).WithTypeAnnotation(EdmCoreModel.Instance.GetInt32(false));
                    ODataPayloadElement b = PayloadBuilder.PrimitiveValue("stringvalue").WithTypeAnnotation(EdmCoreModel.Instance.GetString(false));
                    PrimitiveProperty parametera = new PrimitiveProperty("a", "Edm.Integer", ((PrimitiveValue)a).ClrValue);
                    PrimitiveProperty parameterb = new PrimitiveProperty("b", "Edm.String", ((PrimitiveValue)b).ClrValue);
                    parameterPayload.Add(parametera);
                    parameterPayload.Add(parameterb);
                    parameterPayload.ExpectedFunctionImport((EdmOperationImport)serviceOp1);
                    return parameterPayload;

                case ODataPayloadKind.Unsupported:  // fall through
                default:
                    throw new NotSupportedException();
            }
        }
コード例 #27
0
ファイル: TestParameters.cs プロジェクト: AlineGuan/odata.net
        /// <summary>
        /// Builds a complex instance from the given payloadElements to represent a parameters payload.
        /// </summary>
        /// <param name="payloadElements">Each ODataPayloadElement represents the value for each parameter.</param>
        /// <param name="model">EdmModel instance.</param>
        /// <param name="functionImportName">Name of the function import to add to the model.</param>
        /// <returns></returns>
        private static ComplexInstance PayloadElementsToParameterPayload(ODataPayloadElement[] payloadElements, EdmModel model, string functionImportName)
        {
            EdmOperationImport operationImport = (EdmOperationImport)model.EntityContainer.FindOperationImports(functionImportName).FirstOrDefault();
            EdmOperation operation = (EdmOperation)operationImport.Operation;
            
            var parameterPayload = new ComplexInstance(null, false);
            for (int idx = 0; idx < payloadElements.Length; idx++)
            {
                ODataPayloadElement p = payloadElements[idx];
                string parameterName = "p" + idx;
                PropertyInstance parameter;
                IEdmTypeReference entityModelType = p.GetAnnotation<EntityModelTypeAnnotation>().EdmModelType;
                switch (p.ElementType)
                {
                    case ODataPayloadElementType.PrimitiveValue:
                        object clrValue = ((PrimitiveValue)p).ClrValue;
                        PrimitiveValue primitiveValue = new PrimitiveValue(clrValue == null ? null : clrValue.GetType().FullName, clrValue);
                        primitiveValue.CopyAnnotation<PrimitiveValue, EntityModelTypeAnnotation>(p);
                        parameter = new PrimitiveProperty(parameterName, primitiveValue);
                        operation.AddParameter(parameterName, MetadataUtils.GetPrimitiveTypeReference(primitiveValue.ClrValue.GetType()));
                        break;

                    case ODataPayloadElementType.ComplexInstance:
                        parameter = new ComplexProperty(parameterName, (ComplexInstance)p);
                        operation.AddParameter(parameterName, entityModelType);
                        break;

                    case ODataPayloadElementType.PrimitiveMultiValue:
                        PrimitiveMultiValue primitiveMultiValue = (PrimitiveMultiValue)p;
                        if (primitiveMultiValue.Annotations.OfType<JsonCollectionResultWrapperAnnotation>().SingleOrDefault() == null)
                        {
                            primitiveMultiValue.Annotations.Add(new JsonCollectionResultWrapperAnnotation(false));
                        }

                        parameter = new PrimitiveMultiValueProperty(parameterName, primitiveMultiValue);
                        operation.AddParameter(parameterName, entityModelType);
                        break;

                    case ODataPayloadElementType.ComplexMultiValue:
                        ComplexMultiValue complexMultiValue = (ComplexMultiValue)p;
                        if (complexMultiValue.Annotations.OfType<JsonCollectionResultWrapperAnnotation>().SingleOrDefault() == null)
                        {
                            complexMultiValue.Annotations.Add(new JsonCollectionResultWrapperAnnotation(false));
                        }

                        parameter = new ComplexMultiValueProperty(parameterName, complexMultiValue);
                        operation.AddParameter(parameterName, entityModelType);
                        break;

                    case ODataPayloadElementType.EntityInstance:
                        parameter = new NavigationPropertyInstance(parameterName, (EntityInstance)p);
                        operation.AddParameter(parameterName, entityModelType);
                        break;

                    case ODataPayloadElementType.EntitySetInstance:
                        parameter = new NavigationPropertyInstance(parameterName, (EntitySetInstance)p);
                        operation.AddParameter(parameterName, entityModelType);
                        break;

                    default:
                        throw new NotSupportedException("PayloadElementsToParameterPayload() is called on unsupported ODataPayloadElement type: " + p.ElementType);
                }

                parameterPayload.Add(parameter);
            }

            parameterPayload.ExpectedFunctionImport(operationImport);
            return parameterPayload;
        }