/// <summary> /// Adds or modifies a property's ExpectedTypeODataPayloadElementAnnotation, to aid generation of the context uri. /// </summary> /// <param name="property">The property to annotate.</param> /// <param name="propertyValueType">The type of the property's value.</param> /// <param name="matchesProperty">Delegate for matching the property instance to a MemberProperty.</param> /// <remarks> /// If the method cannot resolve the parent type of the property, one will be created and added to the test descriptor's /// PayloadModel. The descriptor's cached model will be reset. /// </remarks> private void AddExpectedTypeToProperty(PropertyInstance property, IEdmTypeReference propertyValueType, Func <IEdmProperty, bool> matchesProperty) { if (property.Annotations.OfType <JsonLightContextUriAnnotation>().Any()) { return; } var typeAnnotation = property.Annotations.OfType <ExpectedTypeODataPayloadElementAnnotation>().SingleOrDefault(); if (typeAnnotation == null || (typeAnnotation.MemberProperty == null && string.IsNullOrEmpty(typeAnnotation.OpenMemberPropertyName))) { ExpectedTypeODataPayloadElementAnnotation annotation = typeAnnotation ?? new ExpectedTypeODataPayloadElementAnnotation(); IEdmModel model = this.testDescriptor.PayloadEdmModel; var entityType = model.EntityTypes().SingleOrDefault(t => t.Properties().Any(matchesProperty)); if (entityType != null) { annotation.EdmEntitySet = FindEntitySet(model, entityType); annotation.EdmOwningType = entityType; annotation.EdmProperty = entityType.Properties().FirstOrDefault(matchesProperty); } else { var complexType = model.SchemaElements.OfType <IEdmComplexType>().SingleOrDefault(t => t.Properties().Any(matchesProperty)); if (complexType != null) { var complexProperty = complexType.Properties().Single(p => p.Name == property.Name); annotation.EdmOwningType = complexType; annotation.EdmProperty = complexProperty; annotation.EdmExpectedType = complexProperty.Type; } else { // Add new entity type to the model and use that IEdmTypeReference propertyType = annotation.EdmExpectedType ?? propertyValueType; EdmEntityType newEntityType = model.FindDeclaredType("TestModel.NewType") as EdmEntityType; IEdmEntitySet newEntitySet = null; IEdmProperty newProperty = null; string newPorpertyName = property.Name ?? propertyType.FullName() ?? "EmptyName"; if (newEntityType == null) { newEntityType = new EdmEntityType("TestModel", "NewType"); newProperty = newEntityType.AddStructuralProperty(newPorpertyName, propertyType); ((EdmModel)model).AddElement(newEntityType); var container = model.EntityContainersAcrossModels().Single() as EdmEntityContainer; newEntitySet = container.AddEntitySet("NewTypes", newEntityType); } else { newProperty = newEntityType.AddStructuralProperty(newPorpertyName, propertyType); newEntitySet = FindEntitySet(model, newEntityType); } annotation.EdmEntitySet = newEntitySet; annotation.EdmOwningType = newEntityType; annotation.EdmProperty = newProperty; annotation.EdmExpectedType = propertyType; this.testDescriptor.PayloadEdmModel = model; this.testDescriptor.ResetCachedModel(); } } property.SetAnnotation(annotation); } }