public void CanRenamePropertiesInRegularModelBuilder() { HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, BaseAddress + "/explicit/$metadata"); HttpResponseMessage response = Client.SendAsync(request).Result; IEdmModel model = CsdlReader.Parse(XmlReader.Create(response.Content.ReadAsStreamAsync().Result)); // Can change the name of regular, complex and navigation properties. IEdmEntityType customer = model.FindDeclaredType("ModelAliasing.Customer") as IEdmEntityType; Assert.NotNull(customer); Assert.NotNull(customer.FindProperty("FinancialAddress")); Assert.NotNull(customer.FindProperty("ClientName")); Assert.NotNull(customer.FindProperty("Purchases")); // Can change the name of properties on complex objects IEdmComplexType address = model.FindDeclaredType("Location.Direction") as IEdmComplexType; Assert.NotNull(address); Assert.NotNull(address.FindProperty("Reign")); //Can change the name of properties on derived entities. IEdmEntityType expressOrder = model.FindDeclaredType("Purchasing.ExpressOrder") as IEdmEntityType; Assert.NotNull(expressOrder); //Can change the name of properties on derived entities when added explicitly. Assert.NotNull(expressOrder.FindProperty("Fee")); //Data contract attribute doesn't change the name of the property. Assert.Null(expressOrder.FindProperty("DeliveryDate")); Assert.Null(expressOrder.FindProperty("GuanteedDeliveryDate")); // Data contract attribute doesn't change the names of the properties IEdmEntityType ordersLines = model.FindDeclaredType("WebStack.QA.Test.OData.ModelAliasing.ModelAliasingMetadataOrderLine") as IEdmEntityType; Assert.NotNull(ordersLines); Assert.Null(ordersLines.FindProperty("Product")); Assert.NotNull(ordersLines.FindProperty("Item")); // Data contract attribute doesn't override any explicit configuration on the model builder Assert.NotNull(ordersLines.FindProperty("Cost")); }
public async Task CanRenamePropertiesInConventionModelBuilder() { HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, BaseAddress + "/convention/$metadata"); HttpResponseMessage response = await Client.SendAsync(request); IEdmModel model = CsdlReader.Parse(XmlReader.Create(await response.Content.ReadAsStreamAsync())); // Can change the name of regular, complex and navigation properties. IEdmEntityType customer = model.FindDeclaredType("ModelAliasing.Customer") as IEdmEntityType; Assert.NotNull(customer); Assert.NotNull(customer.FindProperty("FinancialAddress")); Assert.NotNull(customer.FindProperty("ClientName")); Assert.NotNull(customer.FindProperty("Purchases")); // Can change the name of properties on complex objects IEdmComplexType address = model.FindDeclaredType("Location.Direction") as IEdmComplexType; Assert.NotNull(address); Assert.NotNull(address.FindProperty("Reign")); //Can change the name of properties on derived entities. IEdmEntityType expressOrder = model.FindDeclaredType("Purchasing.ExpressOrder") as IEdmEntityType; Assert.NotNull(expressOrder); //Can change the name of properties on derived entities when added explicitly. Assert.NotNull(expressOrder.FindProperty("Fee")); //Can change the name of properties on derived entities using data contract attribute. Assert.NotNull(expressOrder.FindProperty("DeliveryDate")); // Can change the name of the properties using DataContract attribute IEdmEntityType ordersLines = model.FindDeclaredType("Billing.OrderLine") as IEdmEntityType; Assert.NotNull(ordersLines); Assert.NotNull(ordersLines.FindProperty("Product")); // Data contract attribute override any explicit configuration on the model builder Assert.NotNull(ordersLines.FindProperty("Cost")); }
public void ReadMetadataDocument_WorksForJsonCSDL() { Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(@"{ ""$Version"": ""4.0"", ""$EntityContainer"": ""NS.Container"", ""NS"": { ""Customer"": { ""$Kind"": ""EntityType"", ""$Key"": [ ""Id"" ], ""Id"": { ""$Type"": ""Edm.Int32"" }, ""Name"": {} }, ""Container"": { ""$Kind"": ""EntityContainer"", ""Customers"": { ""$Collection"": true, ""$Type"": ""NS.Customer"" } } } }")); IODataResponseMessage responseMessage = new InMemoryMessage() { StatusCode = 200, Stream = stream }; responseMessage.SetHeader("Content-Type", "application/json"); ODataMessageReader reader = new ODataMessageReader(responseMessage, new ODataMessageReaderSettings(), new EdmModel()); #if NETCOREAPP3_1 || NETCOREAPP2_1 IEdmModel model = reader.ReadMetadataDocument(); IEdmEntityType customerType = model.FindDeclaredType("NS.Customer") as IEdmEntityType; Assert.NotNull(customerType); IEdmProperty idProperty = customerType.FindProperty("Id"); Assert.NotNull(idProperty); Assert.Equal("Edm.Int32", idProperty.Type.FullName()); IEdmProperty nameProperty = customerType.FindProperty("Name"); Assert.NotNull(nameProperty); Assert.Equal("Edm.String", nameProperty.Type.FullName()); IEdmEntitySet customers = Assert.Single(model.EntityContainer.EntitySets()); Assert.Equal("Customers", customers.Name); Assert.Same(customerType, customers.EntityType()); #else Action test = () => reader.ReadMetadataDocument(); ODataException exception = Assert.Throws <ODataException>(test); Assert.Equal("The JSON metadata is not supported at this platform. It's only supported at platform implementing .NETStardard 2.0.", exception.Message); #endif }
private IEdmNavigationProperty ResolveNavigationPropertyPathForBinding(CsdlNavigationPropertyBinding binding) { Debug.Assert(binding != null, "binding != null"); string bindingPath = binding.Path; Debug.Assert(bindingPath != null, "bindingPath != null"); IEdmEntityType definingType = this.typeCache.GetValue(this, ComputeElementTypeFunc, null); const char Slash = '/'; if (bindingPath.Length == 0 || bindingPath[bindingPath.Length - 1] == Slash) { // if the path did not actually contain a navigation property, then treat it as an unresolved path. // TODO: improve the error given in this case? return(new UnresolvedNavigationPropertyPath(definingType, bindingPath, binding.Location)); } IEdmNavigationProperty navigationProperty; string[] pathSegements = bindingPath.Split(Slash); for (int index = 0; index < pathSegements.Length - 1; index++) { string pathSegement = pathSegements[index]; if (pathSegement.Length == 0) { // TODO: improve the error given in this case? return(new UnresolvedNavigationPropertyPath(definingType, bindingPath, binding.Location)); } IEdmEntityType derivedType = this.container.Context.FindType(pathSegement) as IEdmEntityType; if (derivedType == null) { IEdmProperty property = definingType.FindProperty(pathSegement); navigationProperty = property as IEdmNavigationProperty; if (navigationProperty == null) { return(new UnresolvedNavigationPropertyPath(definingType, bindingPath, binding.Location)); } definingType = navigationProperty.ToEntityType(); } else { definingType = derivedType; } } navigationProperty = definingType.FindProperty(pathSegements.Last()) as IEdmNavigationProperty; if (navigationProperty == null) { // TODO: improve the error given in this case? navigationProperty = new UnresolvedNavigationPropertyPath(definingType, bindingPath, binding.Location); } return(navigationProperty); }
public void LocateEntityContainer() { const string csdl = @"<?xml version=""1.0"" encoding=""utf-16""?> <Schema Namespace=""Hot"" Alias=""Fuzz"" xmlns=""http://docs.oasis-open.org/odata/ns/edm""> <EntityType Name=""Person""> <Key> <PropertyRef Name=""Id"" /> </Key> <Property Name=""Id"" Type=""Int32"" Nullable=""false"" /> <Property Name=""Address"" Type=""String"" MaxLength=""100"" /> </EntityType> <EntityType Name=""Pet""> <Key> <PropertyRef Name=""PetId"" /> </Key> <Property Name=""Id"" Type=""Int32"" Nullable=""false"" /> <Property Name=""OwnerId"" Type=""Int32"" Nullable=""false"" /> </EntityType> <EntityContainer Name=""Wild""> <EntitySet Name=""People"" EntityType=""Hot.Person"" /> <EntitySet Name=""Pets"" EntityType=""Hot.Pet"" /> </EntityContainer> </Schema>"; IEdmModel model; IEnumerable <EdmError> errors; bool parsed = SchemaReader.TryParse(new XmlReader[] { XmlReader.Create(new StringReader(csdl)) }, out model, out errors); Assert.IsTrue(parsed, "parsed"); Assert.IsTrue(errors.Count() == 0, "No errors"); IEdmEntityType person = (IEdmEntityType)model.FindType("Hot.Person"); IEdmProperty personId = person.FindProperty("Id"); IEdmProperty personAddress = person.FindProperty("Address"); IEdmEntityType pet = (IEdmEntityType)model.FindType("Hot.Pet"); IEdmProperty petId = pet.FindProperty("Id"); IEdmProperty ownerId = pet.FindProperty("OwnerId"); IEdmEntityContainer wild = model.EntityContainer; IEdmEntitySet people = model.EntityContainer.FindEntitySet("People"); IEdmEntitySet pets = model.EntityContainer.FindEntitySet("Pets"); AssertCorrectLocation((CsdlLocation)person.Location(), csdl, @"EntityType Name=""Person"""); AssertCorrectLocation((CsdlLocation)personId.Location(), csdl, @"Property Name=""Id"" Type=""Int32"" Nullable=""false"""); AssertCorrectLocation((CsdlLocation)personAddress.Location(), csdl, @"Property Name=""Address"" Type=""String"" MaxLength=""100"" "); AssertCorrectLocation((CsdlLocation)pet.Location(), csdl, @"EntityType Name=""Pet"""); AssertCorrectLocation((CsdlLocation)petId.Location(), csdl, @"Property Name=""Id"" Type=""Int32"" Nullable=""false"" "); AssertCorrectLocation((CsdlLocation)ownerId.Location(), csdl, @"Property Name=""OwnerId"" Type=""Int32"" Nullable=""false"" "); AssertCorrectLocation((CsdlLocation)wild.Location(), csdl, @"EntityContainer Name=""Wild"""); AssertCorrectLocation((CsdlLocation)people.Location(), csdl, @"EntitySet Name=""People"" EntityType=""Hot.Person"" "); AssertCorrectLocation((CsdlLocation)pets.Location(), csdl, @"EntitySet Name=""Pets"" EntityType=""Hot.Pet"" "); }
private static void AnnotationsThreadFunction(object o) { IEdmModel model = (IEdmModel)o; IEdmEntityType person = model.FindEntityType("foo.Person"); IEdmProperty name = person.FindProperty("Name"); string bogus = "http://bogus.com"; string goop = "goop"; string droop = "droop"; string scoop = "scoop"; int index = ++ThreadIndex; for (int i = 0; i < 10000; i++) { var setters = new IEdmDirectValueAnnotationBinding[] { new EdmDirectValueAnnotationBinding(person, bogus, goop, index), new EdmDirectValueAnnotationBinding(person, bogus, droop, index), new EdmDirectValueAnnotationBinding(person, bogus, scoop, index), new EdmDirectValueAnnotationBinding(name, bogus, goop, index), new EdmDirectValueAnnotationBinding(name, bogus, droop, index), new EdmDirectValueAnnotationBinding(name, bogus, scoop, index) }; model.SetAnnotationValues(setters); } }
private IEdmNavigationProperty ComputePartner() { string partnerPropertyName = this.navigationProperty.Partner; IEdmEntityType targetEntityType = this.TargetEntityType; if (partnerPropertyName != null) { var partner = targetEntityType.FindProperty(partnerPropertyName) as IEdmNavigationProperty; if (partner == null) { partner = new UnresolvedNavigationPropertyPath(targetEntityType, partnerPropertyName, this.Location); } return(partner); } foreach (IEdmNavigationProperty potentialPartner in targetEntityType.NavigationProperties()) { if (potentialPartner == this) { continue; } if (potentialPartner.Partner == this) { return(potentialPartner); } } return(null); }
public void PrimitiveExamplevalueInitializeWorksForPrimitiveData(string data, object except) { // Arrange string annotation = $@"<Annotation Term=""Org.OData.Core.V1.Example""> <Record Type=""Org.OData.Core.V1.PrimitiveExampleValue""> <PropertyValue Property=""Description"" String=""Primitive example value"" /> <PropertyValue Property=""Value"" {data} /> </Record> </Annotation>"; IEdmModel model = GetEdmModel(annotation); Assert.NotNull(model); // guard IEdmEntityType customer = model.SchemaElements.OfType <IEdmEntityType>().First(c => c.Name == "Customer"); Assert.NotNull(customer); // guard IEdmProperty dataProperty = customer.FindProperty("Data"); Assert.NotNull(dataProperty); // Act PrimitiveExampleValue value = model.GetRecord <PrimitiveExampleValue>(dataProperty, "Org.OData.Core.V1.Example"); // Assert Assert.NotNull(value); Assert.Equal("Primitive example value", value.Description); Assert.NotNull(value.Value); Assert.Equal(except, value.Value.Value); }
public void EvaluateUnboundTerms() { const string applicationCsdl = @"<Schema Namespace=""bar"" xmlns=""http://docs.oasis-open.org/odata/ns/edm""> <Annotations Target=""bar.Person""> <Annotation Term=""bar.RandomTerm"" Path=""Extra"" /> </Annotations> <EntityType Name=""Person""> <Key> <PropertyRef Name=""Name"" /> </Key> <Property Name=""Name"" Type=""String"" Nullable=""false"" /> <Property Name=""Decoration"" Type=""bar.Decoration""> <Annotation Term=""bar.DecorationTerm"" Qualifier=""Goodness"" String=""Excellent"" /> </Property> </EntityType> <ComplexType Name=""Decoration""> <Property Name=""One"" Type=""Int32"" /> <Property Name=""Two"" Type=""Int32"" /> </ComplexType> </Schema>"; IEdmModel applicationModel = this.Parse(applicationCsdl); IEdmEntityType person = (IEdmEntityType)applicationModel.FindType("bar.Person"); IEdmProperty personDecoration = person.FindProperty("Decoration"); EdmToClrEvaluator evaluator = new EdmToClrEvaluator(null); List <IEdmPropertyValue> decorationPropertyValues = new List <IEdmPropertyValue>(); decorationPropertyValues.Add(new EdmPropertyValue("One", new EdmIntegerConstant(1))); decorationPropertyValues.Add(new EdmPropertyValue("Two", new EdmIntegerConstant(2))); List <IEdmPropertyValue> propertyValues = new List <IEdmPropertyValue>(); propertyValues.Add(new EdmPropertyValue("Name", new EdmStringConstant("Goober"))); propertyValues.Add(new EdmPropertyValue("Decoration", new EdmStructuredValue(null, decorationPropertyValues))); propertyValues.Add(new EdmPropertyValue("Extra", new EdmStringConstant("Extra value!"))); IEdmStructuredValue context = new EdmStructuredValue(new EdmEntityTypeReference(person, false), propertyValues); string random = applicationModel.GetTermValue <string>(context, "bar.RandomTerm", evaluator); Assert.AreEqual("Extra value!", random, "Annotation evaluated value."); IEdmValue randomValue = applicationModel.GetTermValue(context, "bar.RandomTerm", evaluator); Assert.AreEqual("Extra value!", ((IEdmStringValue)randomValue).Value, "Annotation evaluated value."); string goodness = applicationModel.GetTermValue <string>(personDecoration, "bar.DecorationTerm", "Goodness", evaluator); Assert.AreEqual("Excellent", goodness, "Annotation evaluated value."); IEdmValue goodnessValue = applicationModel.GetTermValue(personDecoration, "bar.DecorationTerm", "Goodness", evaluator); Assert.AreEqual("Excellent", ((IEdmStringValue)goodnessValue).Value, "Annotation evaluated value."); IEdmVocabularyAnnotation randomTermAnnotation = applicationModel.FindVocabularyAnnotations <IEdmVocabularyAnnotation>(person, "bar.RandomTerm").Single(); random = evaluator.EvaluateToClrValue <string>(randomTermAnnotation.Value, context); Assert.AreEqual("Extra value!", random, "Annotation evaluated value."); }
/// <summary> /// Validates an <see cref="ODataNavigationLink"/> to ensure all required information is specified and valid. /// </summary> /// <param name="navigationLink">The navigation link to validate.</param> /// <param name="declaringEntityType">The <see cref="IEdmEntityType"/> declaring the navigation property; or null if metadata is not available.</param> /// <param name="expandedPayloadKind">The <see cref="ODataPayloadKind"/> of the expanded content of this navigation link or null for deferred links.</param> /// <returns>The type of the navigation property for this navigation link; or null if no <paramref name="declaringEntityType"/> was specified.</returns> public IEdmNavigationProperty ValidateNavigationLink( ODataNavigationLink navigationLink, IEdmEntityType declaringEntityType, ODataPayloadKind?expandedPayloadKind) { return(declaringEntityType == null ? null : declaringEntityType.FindProperty(navigationLink.Name) as IEdmNavigationProperty); }
public void TryMatchMediaType_DoesnotMatchRequest_ODataEnumValueMediaTypeMappingWithNonRawvalueRequest() { // Arrange IEdmModel model = GetEnumModel(); IEdmEntitySet enumEntity = model.EntityContainer.FindEntitySet("EnumEntity"); IEdmEntityType enumEntityType = model.SchemaElements.OfType <IEdmEntityType>().First(e => e.Name == "EnumEntity"); IEdmStructuralProperty property = enumEntityType.FindProperty("EnumProperty") as IEdmStructuralProperty; Assert.NotNull(property); // Guard PropertySegment propertySegment = new PropertySegment(property); var keys = new[] { new KeyValuePair <string, object>("Id", 1) }; KeySegment keySegment = new KeySegment(keys, enumEntityType, enumEntity); ODataPath path = new ODataPath(new EntitySetSegment(enumEntity), keySegment, propertySegment); ODataEnumValueMediaTypeMapping mapping = new ODataEnumValueMediaTypeMapping(); var request = RequestFactory.Create(HttpMethod.Get, "http://localhost/EnumEntity(1)/EnumProperty/"); request.ODataContext().Path = path; // Act double mapResult = mapping.TryMatchMediaType(request); // Assert Assert.Equal(0, mapResult); }
public void TryMatchMediaType_MatchesRequest_WithEnumRawValue() { // Arrange IEdmModel model = GetEnumModel(); IEdmEntitySet enumEntity = model.EntityContainer.FindEntitySet("EnumEntity"); IEdmEntityType enumEntityType = model.SchemaElements.OfType <IEdmEntityType>().First(e => e.Name == "EnumEntity"); IEdmStructuralProperty property = enumEntityType.FindProperty("EnumProperty") as IEdmStructuralProperty; Assert.NotNull(property); // Guard PropertySegment propertySegment = new PropertySegment(property); var keys = new[] { new KeyValuePair <string, object>("Id", 1) }; KeySegment keySegment = new KeySegment(keys, enumEntityType, enumEntity); ODataPath path = new ODataPath(new EntitySetSegment(enumEntity), keySegment, propertySegment, new ValueSegment(propertySegment.EdmType)); ODataEnumValueMediaTypeMapping mapping = new ODataEnumValueMediaTypeMapping(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/EnumEntity(1)/EnumProperty/$value"); request.ODataProperties().Path = path; // Act double mapResult = mapping.TryMatchMediaType(request); // Assert Assert.Equal(1.0, mapResult); }
private bool IsRequired(PropertyInfo propertyInfo) { IEdmEntityType entityType = GetEntityTypeByName(propertyInfo.DeclaringType.FullName); IEdmProperty edmProperty = entityType.FindProperty(propertyInfo.Name); return(!edmProperty.Type.IsNullable); }
public void TryMatchMediaType_WithNonRawvalueRequest_DoesntMatchRequest() { IEdmModel model = ODataTestUtil.GetEdmModel(); IEdmEntitySet people = model.EntityContainer.FindEntitySet("People"); IEdmEntityType personType = model.SchemaElements.OfType <IEdmEntityType>().First(e => e.Name == "FormatterPerson"); IEdmStructuralProperty ageProperty = personType.FindProperty("Age") as IEdmStructuralProperty; Assert.NotNull(ageProperty); // Guard PropertySegment propertySegment = new PropertySegment(ageProperty); var keys = new[] { new KeyValuePair <string, object>("PerId", 1) }; KeySegment keySegment = new KeySegment(keys, personType, people); ODataPath path = new ODataPath(new EntitySetSegment(people), keySegment, propertySegment); ODataPrimitiveValueMediaTypeMapping mapping = new ODataPrimitiveValueMediaTypeMapping(); var request = RequestFactory.Create(HttpMethod.Get, "http://localhost/People(1)/Age/"); request.ODataContext().Path = path; double mapResult = mapping.TryMatchMediaType(request); Assert.Equal(0, mapResult); }
public void TryMatchMediaType_WithNonRawvalueRequest_DoesntMatchRequest_OnSingleton() { // Arrange IEdmModel model = ODataTestUtil.GetEdmModel(); IEdmSingleton president = model.EntityContainer.FindSingleton("President"); model.SchemaElements.OfType <IEdmEntityType>().First(e => e.Name == "FormatterPerson"); IEdmEntityType personType = model.SchemaElements.OfType <IEdmEntityType>().First(e => e.Name == "FormatterPerson"); IEdmStructuralProperty ageProperty = personType.FindProperty("Age") as IEdmStructuralProperty; Assert.NotNull(ageProperty); // Guard PropertySegment propertySegment = new PropertySegment(ageProperty); ODataPath path = new ODataPath(new SingletonSegment(president), propertySegment); ODataPrimitiveValueMediaTypeMapping mapping = new ODataPrimitiveValueMediaTypeMapping(); var request = RequestFactory.Create(HttpMethod.Get, "http://localhost/President/Age/"); request.ODataContext().Path = path; // Act double mapResult = mapping.TryMatchMediaType(request); // Assert Assert.Equal(0, mapResult); }
private void AddTypeCastsIfNecessary() { IEdmEntityType owningType = null; List <ODataPathSegment> newSegments = new List <ODataPathSegment>(); foreach (ODataPathSegment segment in _segments) { NavigationPropertySegment navProp = segment as NavigationPropertySegment; if (navProp != null && owningType != null && owningType.FindProperty(navProp.NavigationProperty.Name) == null) { // need a type cast TypeSegment typeCast = new TypeSegment( navProp.NavigationProperty.DeclaringType, navigationSource: null); newSegments.Add(typeCast); } newSegments.Add(segment); IEdmEntityType targetEntityType = GetTargetEntityType(segment); if (targetEntityType != null) { owningType = targetEntityType; } } _segments = newSegments; }
/// <summary> /// Tries to resolve the name of a navigation property's target if a server model has been provided. /// </summary> /// <param name="serverSourceTypeName">The name of the server side source type.</param> /// <param name="navigationPropertyName">The name of the navigation property.</param> /// <param name="serverTypeName">The server type name if one could be found.</param> /// <returns>Whether the type name could be found.</returns> internal bool TryResolveNavigationTargetTypeName(string serverSourceTypeName, string navigationPropertyName, out string serverTypeName) { serverTypeName = null; if (this.serviceModel == null || serverSourceTypeName == null) { return(false); } IEdmEntityType parentServerType = this.serviceModel.FindType(serverSourceTypeName) as IEdmEntityType; if (parentServerType == null) { return(false); } IEdmNavigationProperty serverNavigation = parentServerType.FindProperty(navigationPropertyName) as IEdmNavigationProperty; if (serverNavigation == null) { return(false); } IEdmTypeReference targetType = serverNavigation.Type; if (targetType.IsCollection()) { targetType = targetType.AsCollection().ElementType(); } serverTypeName = targetType.FullName(); return(true); }
/// <summary> /// Returns the navigation property for the given payload element (only for entity reference links). /// </summary> /// <param name="expectedTypeAnnotation">The expected type annotation.</param> /// <param name="model">The model to get the navigation property from.</param> /// <returns>The expected navigation property for the specified payload element.</returns> private static IEdmNavigationProperty GetExpectedNavigationProperty(ExpectedTypeODataPayloadElementAnnotation expectedTypeAnnotation, IEdmModel model) { ExceptionUtilities.Assert(model != null, "model != null"); if (expectedTypeAnnotation != null) { if (expectedTypeAnnotation.EdmNavigationProperty != null) { return(expectedTypeAnnotation.EdmNavigationProperty as IEdmNavigationProperty); } NavigationProperty expectedNavigationProperty = expectedTypeAnnotation.NavigationProperty; if (expectedNavigationProperty != null) { NamedStructuralType expectedOwningType = expectedTypeAnnotation.OwningType; ExceptionUtilities.Assert(expectedOwningType != null, "Need an owning type if a navigation property is specified."); IEdmEntityType owningEntityType = model.FindType(expectedOwningType.FullName) as IEdmEntityType; ExceptionUtilities.Assert(owningEntityType != null, "Did not find expected entity type in the model."); IEdmNavigationProperty navigationProperty = owningEntityType.FindProperty(expectedNavigationProperty.Name) as IEdmNavigationProperty; ExceptionUtilities.Assert(navigationProperty != null, "Did not find expected navigation property in the model."); return(navigationProperty); } } return(null); }
public void Term_FunctionApplication_OnNavigationProperty() { this.SetupModelsAndValues(); const string applicationCsdl = @"<Schema Namespace=""Annotations"" xmlns=""http://docs.oasis-open.org/odata/ns/edm""> <Annotations Target=""foo.Person/Address""> <Annotation Term=""bar.StringValue""> <Apply Function=""Functions.StringConcat""> <Path>Zip/Main</Path> <Apply Function=""Functions.StringConcat""> <String>-</String> <Path>Zip/Extension</Path> </Apply> </Apply> </Annotation> </Annotations> </Schema>"; IEdmModel applicationModel = this.Parse(applicationCsdl, this.baseModel, this.vocabularyDefinitionModel, this.operationsModel); EdmExpressionEvaluator expressionEvaluator = new EdmExpressionEvaluator(this.operationsLookup); IEdmEntityType person = this.baseModel.FindEntityType("foo.Person"); IEdmProperty property = person.FindProperty("Address"); IEdmPropertyValue contextPropertyValue = ((IEdmStructuredValue)this.personValue).FindPropertyValue("Address"); IEdmTerm termStringValue = this.vocabularyDefinitionModel.FindTerm("bar.StringValue"); IEdmVocabularyAnnotation annotationString = property.VocabularyAnnotations(applicationModel).SingleOrDefault(a => a.Term == termStringValue); IEdmValue annotationStringValue = expressionEvaluator.Evaluate(annotationString.Value, (IEdmStructuredValue)contextPropertyValue.Value); Assert.AreEqual("98052-0000", ((IEdmStringValue)annotationStringValue).Value, "Term annotation value"); }
public void Term_Path_OnProperty() { this.SetupModelsAndValues(); const string applicationCsdl = @"<Schema Namespace=""Annotations"" xmlns=""http://docs.oasis-open.org/odata/ns/edm""> <Annotations Target=""foo.Person/ContactInfo""> <Annotation Term=""bar.Int16Value"" Qualifier=""WorkPhoneLocal"" Path=""WorkPhone/Local"" /> </Annotations> </Schema>"; IEdmModel applicationModel = this.Parse(applicationCsdl, this.baseModel, this.vocabularyDefinitionModel); EdmExpressionEvaluator expressionEvaluator = new EdmExpressionEvaluator(this.operationsLookup); IEdmEntityType person = this.baseModel.FindEntityType("foo.Person"); IEdmProperty property = person.FindProperty("ContactInfo"); IEdmPropertyValue contextPropertyValue = ((IEdmStructuredValue)this.personValue).FindPropertyValue("ContactInfo"); IEdmTerm termInt16Value = this.vocabularyDefinitionModel.FindTerm("bar.Int16Value"); // ?? Assumes Entity always?? // IEdmValue annotationHotIndex = applicationModel.GetTermValue(contextPropertyValue.Value, termInt16Value, evaluator); IEdmVocabularyAnnotation annotation = property.VocabularyAnnotations(applicationModel).SingleOrDefault(a => a.Term == termInt16Value); IEdmExpression expression = annotation.Value; IEdmValue annotationWorkphoneLocal = expressionEvaluator.Evaluate(expression, (IEdmStructuredValue)contextPropertyValue.Value); Assert.AreEqual(9991234, ((IEdmIntegerValue)annotationWorkphoneLocal).Value, "Term annotation value"); }
public void TryMatchMediaTypeWithBinaryRawValueMatchesRequest_OnODataSingleton() { // Arrange IEdmModel model = GetBinaryModel(); IEdmSingleton rawSingletonValue = model.EntityContainer.FindSingleton("RawSingletonValue"); IEdmEntityType rawValueEntity = model.SchemaElements.OfType <IEdmEntityType>().First(e => e.Name == "RawValueEntity"); IEdmStructuralProperty property = rawValueEntity.FindProperty("BinaryProperty") as IEdmStructuralProperty; Assert.NotNull(property); // Guard PropertySegment propertySegment = new PropertySegment(property); ODataPath path = new ODataPath(new SingletonSegment(rawSingletonValue), propertySegment, new ValueSegment(propertySegment.EdmType)); ODataBinaryValueMediaTypeMapping mapping = new ODataBinaryValueMediaTypeMapping(); var request = RequestFactory.Create(HttpMethod.Get, "http://localhost/RawSingletonValue/BinaryProperty/$value"); request.ODataContext().Path = path; // Act double mapResult = mapping.TryMatchMediaType(request); // Assert Assert.Equal(1.0, mapResult); }
public void TryMatchMediaTypeWithBinaryRawValueMatchesRequest() { IEdmModel model = GetBinaryModel(); IEdmEntitySet rawValues = model.EntityContainer.FindEntitySet("RawValue"); IEdmEntityType rawValueEntity = model.SchemaElements.OfType <IEdmEntityType>().First(e => e.Name == "RawValueEntity"); IEdmStructuralProperty property = rawValueEntity.FindProperty("BinaryProperty") as IEdmStructuralProperty; Assert.NotNull(property); // Guard PropertySegment propertySegment = new PropertySegment(property); var keys = new[] { new KeyValuePair <string, object>("Id", 1) }; KeySegment keySegment = new KeySegment(keys, rawValueEntity, rawValues); ODataPath path = new ODataPath(new EntitySetSegment(rawValues), keySegment, propertySegment, new ValueSegment(propertySegment.EdmType)); ODataBinaryValueMediaTypeMapping mapping = new ODataBinaryValueMediaTypeMapping(); var request = RequestFactory.Create(HttpMethod.Get, "http://localhost/RawValue(1)/BinaryProperty/$value"); request.ODataContext().Path = path; double mapResult = mapping.TryMatchMediaType(request); Assert.Equal(1.0, mapResult); }
/// <summary> /// Gets resource path from service root, and request Uri. /// </summary> /// <param name="baseUri">The service root Uri.</param> /// <param name="odataUri">The request Uri.</param> /// <returns>The resource path.</returns> private Uri GetContainingEntitySetUri(Uri baseUri, ODataUri odataUri) { if (odataUri == null || odataUri.Path == null) { throw new ODataException(OData.Core.Strings.ODataMetadataBuilder_MissingODataUri); } ODataPath path = odataUri.Path; List <ODataPathSegment> segments = path.ToList(); ODataPathSegment lastSegment = segments.Last(); while (!(lastSegment is NavigationPropertySegment)) { segments.Remove(lastSegment); lastSegment = segments.Last(); } // also removed the last navigation property segment segments.Remove(lastSegment); // Remove the unnecessary type cast segment. ODataPathSegment nextToLastSegment = segments.Last(); while (nextToLastSegment is TypeSegment) { ODataPathSegment previousSegment = segments[segments.Count - 2]; IEdmEntityType ownerType = previousSegment.TargetEdmType as IEdmEntityType; if (ownerType != null && ownerType.FindProperty(lastSegment.Identifier) != null) { segments.Remove(nextToLastSegment); nextToLastSegment = segments.Last(); } else { break; } } // append each segment to base uri Uri uri = baseUri; foreach (ODataPathSegment segment in segments) { var keySegment = segment as KeySegment; if (keySegment == null) { uri = this.uriBuilder.BuildEntitySetUri(uri, segment.Identifier); } else { uri = this.uriBuilder.BuildEntityInstanceUri( uri, keySegment.Keys.ToList(), keySegment.EdmType.FullTypeName()); } } return(uri); }
public static IEnumerable <IEdmStructuralProperty> GetConcurrencyProperties(this IEdmModel model, IEdmNavigationSource navigationSource) { Contract.Assert(model != null); Contract.Assert(navigationSource != null); IEnumerable <IEdmStructuralProperty> cachedProperties; if (_concurrencyProperties != null && _concurrencyProperties.TryGetValue(navigationSource, out cachedProperties)) { return(cachedProperties); } IList <IEdmStructuralProperty> results = new List <IEdmStructuralProperty>(); IEdmEntityType entityType = navigationSource.EntityType(); IEdmVocabularyAnnotatable annotatable = navigationSource as IEdmVocabularyAnnotatable; IEdmContainedEntitySet navigationSourceAsEntitySet = navigationSource as IEdmContainedEntitySet; if (navigationSourceAsEntitySet != null) { annotatable = navigationSourceAsEntitySet.NavigationProperty as EdmNavigationProperty; } if (annotatable != null) { IEdmValueAnnotation annotation = model.FindVocabularyAnnotations <IEdmValueAnnotation>(annotatable, CoreVocabularyModel.ConcurrencyTerm).FirstOrDefault(); if (annotation != null) { IEdmCollectionExpression properties = annotation.Value as IEdmCollectionExpression; if (properties != null) { foreach (var property in properties.Elements) { IEdmPathExpression pathExpression = property as IEdmPathExpression; if (pathExpression != null) { // So far, we only consider the single path, because only the direct properties from declaring type are used. // However we have an issue tracking on: https://github.com/OData/WebApi/issues/472 string propertyName = pathExpression.Path.Single(); IEdmProperty edmProperty = entityType.FindProperty(propertyName); IEdmStructuralProperty structuralProperty = edmProperty as IEdmStructuralProperty; if (structuralProperty != null) { results.Add(structuralProperty); } } } } } } if (_concurrencyProperties == null) { _concurrencyProperties = new ConcurrentDictionary <IEdmNavigationSource, IEnumerable <IEdmStructuralProperty> >(); } _concurrencyProperties[navigationSource] = results; return(results); }
public static IEnumerable <IEdmStructuralProperty> GetConcurrencyProperties(this IEdmModel model, IEdmNavigationSource navigationSource) { Contract.Assert(model != null); Contract.Assert(navigationSource != null); // Ensure that concurrency properties cache is attached to model as an annotation to avoid expensive calculations each time ConcurrencyPropertiesAnnotation concurrencyProperties = model.GetAnnotationValue <ConcurrencyPropertiesAnnotation>(model); if (concurrencyProperties == null) { concurrencyProperties = new ConcurrencyPropertiesAnnotation(); model.SetAnnotationValue(model, concurrencyProperties); } IEnumerable <IEdmStructuralProperty> cachedProperties; if (concurrencyProperties.TryGetValue(navigationSource, out cachedProperties)) { return(cachedProperties); } IList <IEdmStructuralProperty> results = new List <IEdmStructuralProperty>(); IEdmEntityType entityType = navigationSource.EntityType(); IEdmVocabularyAnnotatable annotatable = navigationSource as IEdmVocabularyAnnotatable; if (annotatable != null) { var annotations = model.FindVocabularyAnnotations <IEdmVocabularyAnnotation>(annotatable, CoreVocabularyModel.ConcurrencyTerm); IEdmVocabularyAnnotation annotation = annotations.FirstOrDefault(); if (annotation != null) { IEdmCollectionExpression properties = annotation.Value as IEdmCollectionExpression; if (properties != null) { foreach (var property in properties.Elements) { IEdmPathExpression pathExpression = property as IEdmPathExpression; if (pathExpression != null) { // So far, we only consider the single path, because only the direct properties from declaring type are used. // However we have an issue tracking on: https://github.com/OData/WebApi/issues/472 string propertyName = pathExpression.PathSegments.First(); IEdmProperty edmProperty = entityType.FindProperty(propertyName); IEdmStructuralProperty structuralProperty = edmProperty as IEdmStructuralProperty; if (structuralProperty != null) { results.Add(structuralProperty); } } } } } } concurrencyProperties[navigationSource] = results; return(results); }
/// <summary> /// Determines whether or not the given operation is selected and takes type-segments into account. /// </summary> /// <param name="entityType">The current entity type.</param> /// <param name="operation">The operation.</param> /// <param name="mustBeNamespaceQualified">Whether or not the operation name must be container qualified in the $select string.</param> /// <returns> /// <c>true</c> if the operation is selected; otherwise, <c>false</c>. /// </returns> internal bool IsOperationSelected(IEdmEntityType entityType, IEdmOperation operation, bool mustBeNamespaceQualified) { Debug.Assert(entityType != null, "entityType != null"); Debug.Assert(operation != null, "operation != null"); // If the operation name conflicts with a property name then it must be namespace qualified mustBeNamespaceQualified = mustBeNamespaceQualified || entityType.FindProperty(operation.Name) != null; return(this.IsOperationSelectedAtThisLevel(operation, mustBeNamespaceQualified) || this.GetMatchingTypeSegments(entityType).Any(typeSegment => typeSegment.IsOperationSelectedAtThisLevel(operation, mustBeNamespaceQualified))); }
public ODataUriParserInjectionTests() { folderType = oneDriveModel.SchemaElements.OfType <IEdmComplexType>().Single(e => string.Equals(e.Name, "folder")); itemType = oneDriveModel.SchemaElements.OfType <IEdmEntityType>().Single(e => string.Equals(e.Name, "item")); specialItemType = oneDriveModel.SchemaElements.OfType <IEdmEntityType>().Single(e => string.Equals(e.Name, "specialItem")); folderProp = itemType.FindProperty("folder") as IEdmStructuralProperty; sizeProp = itemType.FindProperty("size") as IEdmStructuralProperty; driveType = oneDriveModel.SchemaElements.OfType <IEdmEntityType>().Single(e => string.Equals(e.Name, "drive")); itemsNavProp = driveType.DeclaredNavigationProperties().FirstOrDefault(p => p.Name == "items"); childrenNavProp = itemType.DeclaredNavigationProperties().FirstOrDefault(p => p.Name == "children"); thumbnailsNavProp = itemType.DeclaredNavigationProperties().FirstOrDefault(p => p.Name == "thumbnails"); drivesEntitySet = oneDriveModel.EntityContainer.FindEntitySet("drives"); driveSingleton = oneDriveModel.EntityContainer.FindSingleton("drive"); containedItemsNav = drivesEntitySet.FindNavigationTarget(itemsNavProp); containedthumbnailsNav = containedItemsNav.FindNavigationTarget(thumbnailsNavProp); copyOp = oneDriveModel.SchemaElements.OfType <IEdmOperation>().FirstOrDefault(o => o.Name == "copy"); searchOp = oneDriveModel.SchemaElements.OfType <IEdmOperation>().FirstOrDefault(o => o.Name == "search"); shareItemBindCollectionOp = oneDriveModel.SchemaElements.OfType <IEdmOperation>().LastOrDefault(o => o.Name == "sharedWithMe"); }
public void Term_Constant_OnProperty() { this.SetupModelsAndValues(); const string applicationCsdl = @"<Schema Namespace=""Annotations"" xmlns=""http://docs.oasis-open.org/odata/ns/edm""> <Annotations Target=""foo.Person/CoolnessIndex""> <Annotation Term=""bar.Int32Value"" Qualifier=""HotIndex"" Int=""-1"" /> <Annotation Term=""bar.StringValue"" String=""Goofy"" /> </Annotations> </Schema>"; IEdmModel applicationModel = this.Parse(applicationCsdl, this.baseModel, this.vocabularyDefinitionModel); EdmExpressionEvaluator expressionEvaluator = new EdmExpressionEvaluator(this.operationsLookup); EdmToClrEvaluator clrEvaluator = new EdmToClrEvaluator(this.operationsLookup); IEdmEntityType person = this.baseModel.FindEntityType("foo.Person"); IEdmProperty property = person.FindProperty("CoolnessIndex"); IEdmPropertyValue contextPropertyValue = ((IEdmStructuredValue)this.personValue).FindPropertyValue("CoolnessIndex"); IEdmTerm termInt32Value = this.vocabularyDefinitionModel.FindTerm("bar.Int32Value"); IEdmTerm termStringValue = this.vocabularyDefinitionModel.FindTerm("bar.StringValue"); IEdmVocabularyAnnotation annotation = property.VocabularyAnnotations(applicationModel).SingleOrDefault(a => a.Term == termInt32Value); IEdmExpression expression = annotation.Value; IEdmValue annotationHotIndex = expressionEvaluator.Evaluate(expression); Assert.AreEqual(-1, ((IEdmIntegerValue)annotationHotIndex).Value, "Term annotation value"); annotationHotIndex = applicationModel.GetTermValue(property, termInt32Value, "HotIndex", expressionEvaluator); Assert.AreEqual(-1, ((IEdmIntegerValue)annotationHotIndex).Value, "Term annotation value"); annotationHotIndex = applicationModel.GetTermValue(property, "bar.Int32Value", "HotIndex", expressionEvaluator); Assert.AreEqual(-1, ((IEdmIntegerValue)annotationHotIndex).Value, "Term annotation value"); int hotIndex = applicationModel.GetTermValue <int>(property, termInt32Value, "HotIndex", clrEvaluator); Assert.AreEqual(-1, hotIndex, "Term annotation value"); hotIndex = applicationModel.GetTermValue <int>(property, "bar.Int32Value", "HotIndex", clrEvaluator); Assert.AreEqual(-1, hotIndex, "Term annotation value"); IEdmValue annotationString = applicationModel.GetTermValue(property, termStringValue, expressionEvaluator); Assert.AreEqual("Goofy", ((IEdmStringValue)annotationString).Value, "Term annotation value"); annotationString = applicationModel.GetTermValue(property, "bar.StringValue", expressionEvaluator); Assert.AreEqual("Goofy", ((IEdmStringValue)annotationString).Value, "Term annotation value"); string stringValue = applicationModel.GetTermValue <string>(property, termStringValue, clrEvaluator); Assert.AreEqual("Goofy", stringValue, "Term annotation value"); stringValue = applicationModel.GetTermValue <string>(property, "bar.StringValue", clrEvaluator); Assert.AreEqual("Goofy", stringValue, "Term annotation value"); }
/// <summary> /// Determines whether or not the given operation is selected and takes type-segments into account. /// </summary> /// <param name="entityType">The current entity type.</param> /// <param name="operation">The operation.</param> /// <param name="mustBeContainerQualified">Whether or not the operation name must be container qualified in the $select string.</param> /// <returns> /// <c>true</c> if the operation is selected; otherwise, <c>false</c>. /// </returns> internal bool IsOperationSelected(IEdmEntityType entityType, IEdmFunctionImport operation, bool mustBeContainerQualified) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(entityType != null, "entityType != null"); Debug.Assert(operation != null, "operatio != null"); // If the functionImport name conflicts with a property name then it must be container qualified mustBeContainerQualified = mustBeContainerQualified || entityType.FindProperty(operation.Name) != null; return(this.IsOperationSelectedAtThisLevel(operation, mustBeContainerQualified) || this.GetMatchingTypeSegments(entityType).Any(typeSegment => typeSegment.IsOperationSelectedAtThisLevel(operation, mustBeContainerQualified))); }
/// <summary> /// Resolves a navigation property name to an IEdmNavigationProperty. /// </summary> /// <param name="entityType">Entity Type to look for the navigation property on.</param> /// <param name="navigationPropertyName">Navigation property name to find.</param> /// <returns>Returns the navigation property of throws an exception if it cannot be found.</returns> private IEdmNavigationProperty ResolveNavigationProperty(IEdmEntityType entityType, string navigationPropertyName) { IEdmNavigationProperty navigationProperty = null; IEdmProperty property = entityType.FindProperty(navigationPropertyName); navigationProperty = property as IEdmNavigationProperty; if (navigationProperty == null) { throw new ODataException(ODataErrorStrings.ODataJsonLightMetadataUriParser_InvalidPropertyForEntityReferenceLinkUri(UriUtilsCommon.UriToString(this.parseResult.MetadataUri), navigationPropertyName)); } return(navigationProperty); }
/// <summary> /// Validates an <see cref="ODataNavigationLink"/> to ensure all required information is specified and valid. /// </summary> /// <param name="navigationLink">The navigation link to validate.</param> /// <param name="declaringEntityType">The <see cref="IEdmEntityType"/> declaring the navigation property; or null if metadata is not available.</param> /// <param name="expandedPayloadKind">The <see cref="ODataPayloadKind"/> of the expanded content of this navigation link or null for deferred links.</param> /// <returns>The type of the navigation property for this navigation link; or null if no <paramref name="declaringEntityType"/> was specified.</returns> public IEdmNavigationProperty ValidateNavigationLink( ODataNavigationLink navigationLink, IEdmEntityType declaringEntityType, ODataPayloadKind? expandedPayloadKind) { return declaringEntityType == null ? null : declaringEntityType.FindProperty(navigationLink.Name) as IEdmNavigationProperty; }
internal static IEdmNavigationProperty ValidateNavigationLink( ODataNavigationLink navigationLink, IEdmEntityType declaringEntityType, ODataPayloadKind? expandedPayloadKind, bool bypassValidation = false) { Debug.Assert(navigationLink != null, "navigationLink != null"); Debug.Assert( !expandedPayloadKind.HasValue || expandedPayloadKind.Value == ODataPayloadKind.EntityReferenceLink || expandedPayloadKind.Value == ODataPayloadKind.Entry || expandedPayloadKind.Value == ODataPayloadKind.Feed, "If an expanded payload kind is specified it must be entry, feed or entity reference link."); if (bypassValidation) { return declaringEntityType == null ? null : declaringEntityType.FindProperty(navigationLink.Name) as IEdmNavigationProperty; } // Navigation link must have a non-empty name if (string.IsNullOrEmpty(navigationLink.Name)) { throw new ODataException(Strings.ValidationUtils_LinkMustSpecifyName); } // If we write an entity reference link, don't validate the multiplicity of the IsCollection // property if it is 'false' (since we allow writing a singleton navigation link for // a collection navigation property in requests) nor the consistency of payload kind and metadata // (which is done separately in ODataWriterCore.CheckForNavigationLinkWithContent). bool isEntityReferenceLinkPayload = expandedPayloadKind == ODataPayloadKind.EntityReferenceLink; // true only if the expandedPayloadKind has a value and the value is 'Feed' bool isFeedPayload = expandedPayloadKind == ODataPayloadKind.Feed; // Make sure the IsCollection property agrees with the payload kind for entry and feed payloads Func<object, string> errorTemplate = null; if (!isEntityReferenceLinkPayload && navigationLink.IsCollection.HasValue && expandedPayloadKind.HasValue) { // For feed/entry make sure the IsCollection property is set correctly. if (isFeedPayload != navigationLink.IsCollection.Value) { errorTemplate = expandedPayloadKind.Value == ODataPayloadKind.Feed ? (Func<object, string>)Strings.WriterValidationUtils_ExpandedLinkIsCollectionFalseWithFeedContent : Strings.WriterValidationUtils_ExpandedLinkIsCollectionTrueWithEntryContent; } } IEdmNavigationProperty navigationProperty = null; if (errorTemplate == null && declaringEntityType != null) { navigationProperty = WriterValidationUtils.ValidateNavigationPropertyDefined(navigationLink.Name, declaringEntityType); Debug.Assert(navigationProperty != null, "If we have a declaring type we expect a non-null navigation property since open nav props are not allowed."); bool isCollectionType = navigationProperty.Type.TypeKind() == EdmTypeKind.Collection; // Make sure the IsCollection property agrees with the metadata type for entry and feed payloads if (navigationLink.IsCollection.HasValue && isCollectionType != navigationLink.IsCollection) { // Ignore the case where IsCollection is 'false' and we are writing an entity reference link // (see comment above) if (!(navigationLink.IsCollection == false && isEntityReferenceLinkPayload)) { errorTemplate = isCollectionType ? (Func<object, string>)Strings.WriterValidationUtils_ExpandedLinkIsCollectionFalseWithFeedMetadata : Strings.WriterValidationUtils_ExpandedLinkIsCollectionTrueWithEntryMetadata; } } // Make sure that the payload kind agrees with the metadata. // For entity reference links we check separately in ODataWriterCore.CheckForNavigationLinkWithContent. if (!isEntityReferenceLinkPayload && expandedPayloadKind.HasValue && isCollectionType != isFeedPayload) { errorTemplate = isCollectionType ? (Func<object, string>)Strings.WriterValidationUtils_ExpandedLinkWithEntryPayloadAndFeedMetadata : Strings.WriterValidationUtils_ExpandedLinkWithFeedPayloadAndEntryMetadata; } } if (errorTemplate != null) { string uri = navigationLink.Url == null ? "null" : UriUtils.UriToString(navigationLink.Url); throw new ODataException(errorTemplate(uri)); } return navigationProperty; }
/// <summary> /// Determines whether or not the given operation is selected and takes type-segments into account. /// </summary> /// <param name="entityType">The current entity type.</param> /// <param name="operation">The operation.</param> /// <param name="mustBeNamespaceQualified">Whether or not the operation name must be container qualified in the $select string.</param> /// <returns> /// <c>true</c> if the operation is selected; otherwise, <c>false</c>. /// </returns> internal bool IsOperationSelected(IEdmEntityType entityType, IEdmOperation operation, bool mustBeNamespaceQualified) { Debug.Assert(entityType != null, "entityType != null"); Debug.Assert(operation != null, "operation != null"); // If the operation name conflicts with a property name then it must be namespace qualified mustBeNamespaceQualified = mustBeNamespaceQualified || entityType.FindProperty(operation.Name) != null; return this.IsOperationSelectedAtThisLevel(operation, mustBeNamespaceQualified) || this.GetMatchingTypeSegments(entityType).Any(typeSegment => typeSegment.IsOperationSelectedAtThisLevel(operation, mustBeNamespaceQualified)); }