/// <summary> /// Creates a set of interesting complex values along with metadata. /// </summary> /// <param name="model">If non-null, the method creates complex types for the complex values and adds them to the model.</param> /// <param name="withTypeNames">true if the complex value payloads should specify type names.</param> /// <param name="fullSet">true if all available complex values should be returned, false if only the most interesting subset should be returned.</param> /// <returns>List of interesting complex values.</returns> public static IEnumerable<ComplexInstance> CreateComplexValues(EdmModel model, bool withTypeNames, bool fullSet = true) { var complexValuesList = new List<ComplexInstance>(); EdmComplexType complexType = null; EdmComplexType innerComplexType = null; string typeName; ComplexInstance complexValue; // Null complex value if (fullSet) { typeName = "NullComplexType"; // Can't specify type name for a null complex value since the reader will not read it (in JSON it's not even in the payload anywhere) complexValue = new ComplexInstance(null, true); complexValuesList.Add(complexValue); if (model != null) { complexType = (EdmComplexType)model.FindDeclaredType(GetFullTypeName(typeName)); if (complexType == null) { complexType = new EdmComplexType(NamespaceName, typeName); model.AddElement(complexType); } complexValue.WithTypeAnnotation(new EdmComplexTypeReference(complexType, true)); } } if (fullSet) { // Complex value with one number property typeName = "ComplexTypeWithNumberProperty"; complexValue = PayloadBuilder.ComplexValue(withTypeNames ? GetFullTypeName(typeName) : null) .PrimitiveProperty("numberProperty", 42); complexValuesList.Add(complexValue); if (model != null) { complexType = model.FindDeclaredType(GetFullTypeName(typeName)) as EdmComplexType; if (complexType == null) { complexType = new EdmComplexType(NamespaceName, typeName); complexType.AddStructuralProperty("numberProperty", EdmPrimitiveTypeKind.Int32); model.AddElement(complexType); } complexValue.WithTypeAnnotation(complexType); } } // Complex value with three properties typeName = "ComplexTypeWithNumberStringAndNullProperty"; complexValue = PayloadBuilder.ComplexValue(withTypeNames ? GetFullTypeName(typeName) : null) .PrimitiveProperty("number", 42) .PrimitiveProperty("string", "some") .PrimitiveProperty("null", null); complexValuesList.Add(complexValue); if (model != null) { complexType = model.FindDeclaredType(GetFullTypeName(typeName)) as EdmComplexType; if (complexType == null) { complexType = new EdmComplexType(NamespaceName, typeName); complexType.AddStructuralProperty("number", EdmPrimitiveTypeKind.Int32); complexType.AddStructuralProperty("string", EdmPrimitiveTypeKind.String); complexType.AddStructuralProperty("null", EdmPrimitiveTypeKind.String); model.AddElement(complexType); } complexValue.WithTypeAnnotation(complexType); } // Complex value with primitive and complex property typeName = "ComplexTypeWithPrimitiveAndComplexProperty"; if (model != null) { innerComplexType = model.FindDeclaredType(GetFullTypeName("InnerComplexTypeWithStringProperty")) as EdmComplexType; if (innerComplexType == null) { innerComplexType = new EdmComplexType(NamespaceName, "InnerComplexTypeWithStringProperty"); innerComplexType.AddStructuralProperty("foo", EdmPrimitiveTypeKind.String); model.AddElement(innerComplexType); } complexType = model.FindDeclaredType(GetFullTypeName(typeName)) as EdmComplexType; if (complexType == null) { complexType = new EdmComplexType(NamespaceName, typeName); complexType.AddStructuralProperty("number", EdmPrimitiveTypeKind.Int32); complexType.AddStructuralProperty("complex", innerComplexType.ToTypeReference()); model.AddElement(complexType); } } complexValue = PayloadBuilder.ComplexValue(withTypeNames ? GetFullTypeName(typeName) : null) .PrimitiveProperty("number", 42) .Property("complex", (withTypeNames ? PayloadBuilder.ComplexValue("TestModel.InnerComplexTypeWithStringProperty") : (model != null ? PayloadBuilder.ComplexValue(null).AddAnnotation(new SerializationTypeNameTestAnnotation() { TypeName = null }) : PayloadBuilder.ComplexValue(null))) .PrimitiveProperty("foo", "bar") .WithTypeAnnotation(innerComplexType)); complexValuesList.Add(complexValue); complexValue.WithTypeAnnotation(complexType); // Complex value with spatial properties typeName = "ComplexTypeWithSpatialProperties"; if (model != null) { complexType = model.FindDeclaredType(GetFullTypeName(typeName)) as EdmComplexType; if (complexType == null) { complexType = new EdmComplexType(NamespaceName, typeName); complexType.AddStructuralProperty("geographyPoint", EdmPrimitiveTypeKind.GeographyPoint); complexType.AddStructuralProperty("geometryPoint", EdmPrimitiveTypeKind.GeometryPoint); model.AddElement(complexType); } } complexValue = PayloadBuilder.ComplexValue(withTypeNames ? GetFullTypeName(typeName) : null) .PrimitiveProperty("geographyPoint", GeographyFactory.Point(32.0, -200.0).Build()) .PrimitiveProperty("geometryPoint", GeometryFactory.Point(60.5, -50.0).Build()); complexValuesList.Add(complexValue); complexValue.WithTypeAnnotation(complexType); // Complex value with deeply nested complex types if (fullSet) { int nesting = 7; var nestedComplexTypes = new List<EdmComplexType>(); string typeNameBase = "NestedComplexType"; if (model != null) { for (int i = 0; i < nesting; ++i) { typeName = typeNameBase + i; complexType = model.FindDeclaredType(GetFullTypeName(typeName)) as EdmComplexType; if (complexType == null) { complexType = new EdmComplexType(NamespaceName, typeName); complexType.AddStructuralProperty("Property1", EdmPrimitiveTypeKind.Int32); if (nestedComplexTypes.Any()) { complexType.AddStructuralProperty("complex", nestedComplexTypes.Last().ToTypeReference()); } model.AddElement(complexType); } nestedComplexTypes.Add(complexType); } } complexValue = PayloadBuilder.ComplexValue(withTypeNames ? GetFullTypeName(typeNameBase) + "0" : null) .PrimitiveProperty("Property1", 0) .WithTypeAnnotation(nestedComplexTypes.ElementAt(0)); for (int j = 1; j < nesting; ++j) { if (!withTypeNames && model != null) { complexValue.AddAnnotation(new SerializationTypeNameTestAnnotation() { TypeName = null }); } complexValue = PayloadBuilder.ComplexValue(withTypeNames ? GetFullTypeName(typeNameBase) + j : null) .PrimitiveProperty("Property1", 0) .Property("complex", complexValue); complexValue.WithTypeAnnotation(nestedComplexTypes.ElementAt(j)); } complexValuesList.Add(complexValue); } // Complex value with many primitive properties if (fullSet) { var primitiveValues = TestValues.CreatePrimitiveValuesWithMetadata(true); typeName = "ComplexTypeWithManyPrimitiveProperties"; if (model != null) { complexType = model.FindDeclaredType(GetFullTypeName(typeName)) as EdmComplexType; if (complexType == null) { complexType = new EdmComplexType(NamespaceName, typeName); for (int i = 0; i < primitiveValues.Count; ++i) { complexType.AddStructuralProperty("property" + i, primitiveValues[i].GetAnnotation<EntityModelTypeAnnotation>().EdmModelType); } model.AddElement(complexType); } } complexValue = PayloadBuilder.ComplexValue(withTypeNames ? GetFullTypeName(typeName) : null).WithTypeAnnotation(complexType); for (int j = 0; j < primitiveValues.Count; ++j) { complexValue.PrimitiveProperty("property" + j, primitiveValues[j].ClrValue); } complexValuesList.Add(complexValue); } // Complex value with collection properties if (fullSet) { var primitiveCollections = TestValues.CreatePrimitiveCollections(withTypeNames, true); var complexPropertyValue = complexValuesList.Last().DeepCopy(); IEdmTypeReference complexPropertyType = null; typeName = "ComplexTypeWithCollectionProperties"; if (model != null) { complexType = model.FindDeclaredType(GetFullTypeName(typeName)) as EdmComplexType; if (complexType == null) { complexType = new EdmComplexType(NamespaceName, typeName); int i = 0; for (; i < primitiveCollections.Count(); ++i) { complexType.AddStructuralProperty("property" + i, primitiveCollections.ElementAt(i).GetAnnotation<EntityModelTypeAnnotation>().EdmModelType); } complexPropertyType = complexPropertyValue.GetAnnotation<EntityModelTypeAnnotation>().EdmModelType; complexType.AddStructuralProperty("property" + i, EdmCoreModel.GetCollection(complexPropertyType)); model.AddElement(complexType); } } complexValue = PayloadBuilder.ComplexValue(withTypeNames ? GetFullTypeName(typeName) : null).WithTypeAnnotation(complexType); int k = 0; for (; k < primitiveCollections.Count(); ++k) { complexValue.Property("property" + k, primitiveCollections.ElementAt(k)); } string complexCollectionTypeName = withTypeNames ? EntityModelUtils.GetCollectionTypeName(complexPropertyValue.FullTypeName) : null; var complexCollectionItem = PayloadBuilder.ComplexMultiValue(complexCollectionTypeName) .Item(complexPropertyValue) .WithTypeAnnotation(EdmCoreModel.GetCollection(complexPropertyType)); if (!withTypeNames && model != null) { complexPropertyValue.AddAnnotation(new SerializationTypeNameTestAnnotation() { TypeName = null }); complexCollectionItem.AddAnnotation(new SerializationTypeNameTestAnnotation() { TypeName = null }); } complexValue.Property( "property" + k, complexCollectionItem); complexValuesList.Add(complexValue); } if (model != null) { if (!withTypeNames) { foreach (var item in complexValuesList) { item.AddAnnotation(new SerializationTypeNameTestAnnotation() { TypeName = null }); } } if (model.EntityContainer == null) { model.AddElement(new EdmEntityContainer(NamespaceName, "DefaultContainer")); } } return complexValuesList; }