internal static bool TryCastPathAsType(this IEdmPathExpression expression, IEdmTypeReference type, IEdmType context, bool matchExactly, out IEnumerable <EdmError> discoveredErrors) { IEdmStructuredType structuredContext = context as IEdmStructuredType; if (structuredContext != null) { IEdmType result = context; // [EdmLib] Need to handle paths that bind to things other than properties. foreach (string segment in expression.PathSegments) { IEdmStructuredType structuredResult = result as IEdmStructuredType; if (structuredResult == null) { discoveredErrors = new EdmError[] { new EdmError(expression.Location(), EdmErrorCode.PathIsNotValidForTheGivenContext, Edm.Strings.EdmModel_Validator_Semantic_PathIsNotValidForTheGivenContext(segment)) }; return(false); } IEdmProperty resultProperty = structuredResult.FindProperty(segment); result = (resultProperty != null) ? resultProperty.Type.Definition : null; // If the path is not resolved, it could refer to an open type, and we cannot make an assertion about its type. if (result == null) { discoveredErrors = Enumerable.Empty <EdmError>(); return(true); } } return(TestTypeMatch(result, type.Definition, expression.Location(), matchExactly, out discoveredErrors)); } discoveredErrors = Enumerable.Empty <EdmError>(); return(true); }
/// <summary> /// Resolve property from property name /// </summary> /// <param name="type">The declaring type.</param> /// <param name="propertyName">The property name.</param> /// <returns>The resolved <see cref="IEdmProperty"/></returns> public virtual IEdmProperty ResolveProperty(IEdmStructuredType type, string propertyName) { IEdmProperty property = type.FindProperty(propertyName); if (property != null || !EnableCaseInsensitive) { return(property); } var result = type.Properties() .Where(_ => string.Equals(propertyName, _.Name, StringComparison.OrdinalIgnoreCase)); IEdmProperty resolvedProperty = null; foreach (IEdmProperty candidate in result) { if (resolvedProperty == null) { resolvedProperty = candidate; } else { throw new ODataException(Strings.UriParserMetadata_MultipleMatchingPropertiesFound(propertyName, type.FullTypeName())); } } return(resolvedProperty); }
/// <summary> /// Returns the structural property for the given payload element (only for properties). /// </summary> /// <param name="expectedTypeAnnotation">The expected type annotation.</param> /// <param name="model">The model to get the structural property from.</param> /// <returns>The expected structural property for the specified payload element.</returns> private static IEdmStructuralProperty GetExpectedStructuralProperty(ExpectedTypeODataPayloadElementAnnotation expectedTypeAnnotation, IEdmModel model) { ExceptionUtilities.Assert(model != null, "model != null"); if (expectedTypeAnnotation != null) { if (expectedTypeAnnotation.EdmProperty != null) { return(expectedTypeAnnotation.EdmProperty as IEdmStructuralProperty); } MemberProperty expectedStructuralProperty = expectedTypeAnnotation.MemberProperty; if (expectedStructuralProperty != null) { NamedStructuralType expectedOwningType = expectedTypeAnnotation.OwningType; ExceptionUtilities.Assert(expectedOwningType != null, "Need an owning type if a structural property is specified."); IEdmStructuredType owningType = model.FindType(expectedOwningType.FullName) as IEdmStructuredType; ExceptionUtilities.Assert(owningType != null, "Did not find expected structured type in the model."); IEdmStructuralProperty structuralProperty = owningType.FindProperty(expectedStructuralProperty.Name) as IEdmStructuralProperty; ExceptionUtilities.Assert(structuralProperty != null, "Did not find expected structural property in the model."); return(structuralProperty); } } return(null); }
/// <summary> /// Sets the expected property for the top-level property instance. /// </summary> /// <param name="property">The property instance to set the expected property for.</param> /// <param name="owningType">The type owning the expected property.</param> /// <param name="expectedPropertyName">The name of the property to set as the expected property.</param> /// <returns>The <paramref name="property"/> after its expected property was set.</returns> public static PropertyInstance ExpectedProperty( this PropertyInstance property, IEdmStructuredType owningType, string expectedPropertyName) { ExceptionUtilities.CheckArgumentNotNull(property, "property"); ExceptionUtilities.CheckArgumentNotNull(owningType, "owningType"); ExceptionUtilities.CheckStringArgumentIsNotNullOrEmpty(expectedPropertyName, "expectedPropertyName"); ExpectedTypeODataPayloadElementAnnotation annotation = ODataPayloadElementExtensions.AddExpectedTypeAnnotation(property); annotation.EdmOwningType = owningType; var memberProperty = owningType.FindProperty(expectedPropertyName); if (memberProperty != null) { annotation.EdmProperty = memberProperty; annotation.EdmExpectedType = memberProperty.Type; } else { ExceptionUtilities.Assert(owningType.IsOpen, "For non-declared properties the owning type must be open."); annotation.OpenMemberPropertyName = expectedPropertyName; } return(property); }
public PropertyMetadataTypeInfo(string name, IEdmStructuredType owningType) { this.PropertyName = name; this.OwningType = owningType; this.EdmProperty = owningType == null ? null : owningType.FindProperty(name); this.IsUndeclaredProperty = this.EdmProperty == null; this.IsOpenProperty = (owningType != null && owningType.IsOpen && this.IsUndeclaredProperty); this.TypeReference = this.IsUndeclaredProperty ? null : this.EdmProperty.Type; this.FullName = this.TypeReference == null ? null : this.TypeReference.Definition.AsActualType().FullTypeName(); }
/// <summary> /// Translates a V3 SingleNavigationNode to V4 SingleNavigationNode /// </summary> /// <param name="nodeIn">V3 SingleNavigationNode</param> /// <returns>V4 SingleNavigationNode</returns> public override QueryNode Visit(Data.OData.Query.SemanticAst.SingleNavigationNode nodeIn) { IEdmStructuredType v4Type = v4model.GetV4Definition(nodeIn.TypeReference.Definition) as IEdmStructuredType; ExceptionUtil.IfNullThrowException(v4Type, "Unable to locate v4 type " + nodeIn.TypeReference.Definition.GetFullTypeName()); IEdmNavigationProperty v4navProperty = v4Type.FindProperty(nodeIn.NavigationProperty.Name) as IEdmNavigationProperty; ExceptionUtil.IfNullThrowException(v4Type, "Unable to locate v4 navigation property " + nodeIn.NavigationProperty.Name); return new SingleNavigationNode((SingleResourceNode)nodeIn.Source.Accept(this), v4navProperty, null); }
/// <summary> /// Determines whether or not the given operation is selected and takes type-segments into account. /// </summary> /// <param name="structuredType">The current resource 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(IEdmStructuredType structuredType, IEdmOperation operation, bool mustBeNamespaceQualified) { Debug.Assert(structuredType != null, "structuredType != null"); Debug.Assert(operation != null, "operation != null"); // If the operation name conflicts with a property name then it must be namespace qualified mustBeNamespaceQualified = mustBeNamespaceQualified || structuredType.FindProperty(operation.Name) != null; return(this.IsOperationSelectedAtThisLevel(operation, mustBeNamespaceQualified) || this.GetMatchingTypeSegments(structuredType).Any(typeSegment => typeSegment.IsOperationSelectedAtThisLevel(operation, mustBeNamespaceQualified))); }
/// <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) { ODataPath path = odataUri.Path; List <ODataPathSegment> segments = path.ToList(); ODataPathSegment lastSegment = segments.Last(); while (!(lastSegment is NavigationPropertySegment) && !(lastSegment is OperationSegment)) { 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]; IEdmStructuredType owningType = previousSegment.TargetEdmType as IEdmStructuredType; if (owningType != null && owningType.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); }
/// <summary> /// Validates that a property with the specified name exists on a given structured type. /// The structured type can be null if no metadata is available. /// </summary> /// <param name="propertyName">The name of the property to validate.</param> /// <param name="owningStructuredType">The owning type of the property with name <paramref name="propertyName"/> /// or null if no metadata is available.</param> /// <param name="throwOnMissingProperty">Whether throw exception on missing property.</param> /// <returns>The <see cref="IEdmProperty"/> instance representing the property with name <paramref name="propertyName"/> /// or null if no metadata is available.</returns> public IEdmProperty ValidatePropertyDefined( string propertyName, IEdmStructuredType owningStructuredType, bool throwOnMissingProperty = true) { if (owningStructuredType == null) { return null; } return owningStructuredType.FindProperty(propertyName); }
/// <summary> /// Validates that a property with the specified name exists on a given structured type. /// The structured type can be null if no metadata is available. /// </summary> /// <param name="propertyName">The name of the property to validate.</param> /// <param name="owningStructuredType">The owning type of the property with name <paramref name="propertyName"/> /// or null if no metadata is available.</param> /// <param name="throwOnMissingProperty">Whether throw exception on missing property.</param> /// <returns>The <see cref="IEdmProperty"/> instance representing the property with name <paramref name="propertyName"/> /// or null if no metadata is available.</returns> public IEdmProperty ValidatePropertyDefined( string propertyName, IEdmStructuredType owningStructuredType, bool throwOnMissingProperty = true) { if (owningStructuredType == null) { return(null); } return(owningStructuredType.FindProperty(propertyName)); }
public PropertyMetadataTypeInfo(IEdmModel model, string name, IEdmStructuredType owningType) { this.PropertyName = name; this.OwningType = owningType; this.EdmProperty = owningType == null ? null : owningType.FindProperty(name); this.IsUndeclaredProperty = this.EdmProperty == null; this.IsOpenProperty = (owningType != null && owningType.IsOpen && this.IsUndeclaredProperty); this.TypeReference = this.IsUndeclaredProperty ? null : this.EdmProperty.Type; this.FullName = this.TypeReference == null ? null : this.TypeReference.Definition.AsActualType().FullTypeName(); this.model = model; derivedTypeConstraintsLoaded = false; }
internal static IEdmProperty FindDefinedProperty(string propertyName, IEdmStructuredType owningStructuredType, ODataMessageReaderSettings messageReaderSettings) { if (owningStructuredType == null) { return null; } IEdmProperty property = owningStructuredType.FindProperty(propertyName); if (((property == null) && owningStructuredType.IsOpen) && (messageReaderSettings.UndeclaredPropertyBehaviorKinds != ODataUndeclaredPropertyBehaviorKinds.None)) { throw new ODataException(Microsoft.Data.OData.Strings.ReaderValidationUtils_UndeclaredPropertyBehaviorKindSpecifiedForOpenType(propertyName, owningStructuredType.ODataFullName())); } return property; }
/// <summary> /// Translates a v3 NavigationPropertyLinkSegment (TODO: EXAMPLE) into v4 NavigationPropertyLinkSegment /// </summary> /// <param name="segment">OData V3 NavigationPropertyLinkSegment</param> /// <returns>OData V4 NavigationPropertyLinkSegment</returns> public override ODataPathSegment Translate(Data.OData.Query.SemanticAst.NavigationPropertyLinkSegment segment) { ExceptionUtil.IfArgumentNullThrowException(segment.EntitySet, "segment.EntitySet", "V3 entity set not found"); IEdmStructuredType v4Type = v4model.GetV4Definition(segment.NavigationProperty.DeclaringType) as IEdmStructuredType; IEdmNavigationProperty v4navigationProperty = v4Type.FindProperty(segment.NavigationProperty.Name) as IEdmNavigationProperty; ExceptionUtil.IfNullThrowException(v4Type, "Unable to find equivalent V4 property of V3 property: " + segment.NavigationProperty.Name); IEdmNavigationSource v4navigationSource = v4model.FindDeclaredNavigationSource(segment.EntitySet.Name); ExceptionUtil.IfNullThrowException(v4navigationSource, "Unable to find equivalent V4 entity set of V3 Entity set " + segment.EntitySet.Name); return(new NavigationPropertyLinkSegment(v4navigationProperty, v4navigationSource)); }
internal static IEdmProperty FindDefinedProperty(string propertyName, IEdmStructuredType owningStructuredType, ODataMessageReaderSettings messageReaderSettings) { if (owningStructuredType == null) { return(null); } IEdmProperty property = owningStructuredType.FindProperty(propertyName); if (((property == null) && owningStructuredType.IsOpen) && (messageReaderSettings.UndeclaredPropertyBehaviorKinds != ODataUndeclaredPropertyBehaviorKinds.None)) { throw new ODataException(Microsoft.Data.OData.Strings.ReaderValidationUtils_UndeclaredPropertyBehaviorKindSpecifiedForOpenType(propertyName, owningStructuredType.ODataFullName())); } return(property); }
/// <summary> /// Translates at V3 PropertySegment (e.g. "/Boxes(1)/Name") into a V4 PropertySegment /// </summary> /// <param name="segment">OData V3 PropertySegment</param> /// <returns>OData V4 PropertySegment</returns> public override ODataPathSegment Translate(Data.OData.Query.SemanticAst.PropertySegment segment) { // Look up equivalent declaring type in V4 model IEdmStructuredType v4Type = v4model.GetV4Definition(segment.Property.DeclaringType) as IEdmStructuredType; ExceptionUtil.IfNullThrowException(v4Type, "Unable to locate equivalent v4 type for " + segment.Property.DeclaringType.GetFullTypeName()); // Look up corresponding Property in V4 Type by name IEdmStructuralProperty v4Property = v4Type.FindProperty(segment.Property.Name) as IEdmStructuralProperty; ExceptionUtil.IfNullThrowException(v4Property, "Unable to locate equivalent v4 property for " + segment.Property.Name); return(new PropertySegment(v4Property)); }
/// <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) { ODataPath path = odataUri.Path; List <ODataPathSegment> segments = path.ToList(); int lastIndex = segments.Count - 1; ODataPathSegment lastSegment = segments[lastIndex]; while (!(lastSegment is NavigationPropertySegment) && !(lastSegment is OperationSegment)) { lastSegment = segments[--lastIndex]; } while (lastSegment is TypeSegment) { ODataPathSegment previousSegment = segments[lastIndex - 1]; IEdmStructuredType owningType = previousSegment.TargetEdmType as IEdmStructuredType; if (owningType != null && owningType.FindProperty(lastSegment.Identifier) != null) { lastSegment = segments[--lastIndex]; } else { break; } } // trim all the un-needed segments segments = segments.GetRange(0, lastIndex); // 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); }
internal static IEdmProperty ValidatePropertyDefined(string propertyName, IEdmStructuredType owningStructuredType) { if (owningStructuredType == null) { return(null); } IEdmProperty property = owningStructuredType.FindProperty(propertyName); if (!owningStructuredType.IsOpen && (property == null)) { throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_PropertyDoesNotExistOnType(propertyName, owningStructuredType.ODataFullName())); } return(property); }
public static IEdmProperty ResolveProperty(this IEdmStructuredType type, string propertyName, bool enableCaseInsensitive = false) { IEdmProperty property = type.FindProperty(propertyName); if (property != null || !enableCaseInsensitive) { return(property); } var result = type.Properties() .Where(_ => string.Equals(propertyName, _.Name, StringComparison.OrdinalIgnoreCase)) .ToList(); return(result.SingleOrDefault()); }
/// <summary> /// Translates V3 CollectionNavigationNode to V4 CollectionNavigationNode /// </summary> /// <param name="nodeIn">V3 CollectionNavigationNode</param> /// <returns>V4 CollectionNavigationNode</returns> public override QueryNode Visit(Data.OData.Query.SemanticAst.CollectionNavigationNode nodeIn) { IEdmPathExpression pathExpr = null; if (nodeIn.EntitySet != null) { IEdmNavigationSource navigationSource = v4model.FindDeclaredNavigationSource(nodeIn.EntitySet.Name); pathExpr = navigationSource.Path; } IEdmStructuredType v4Type = v4model.GetV4Definition(nodeIn.NavigationProperty.DeclaringType) as IEdmStructuredType; ExceptionUtil.IfNullThrowException(v4Type, "Unable to locate v4 structured type " + nodeIn.NavigationProperty.DeclaringType.GetFullTypeName()); IEdmNavigationProperty v4navProperty = v4Type.FindProperty(nodeIn.NavigationProperty.Name) as IEdmNavigationProperty; ExceptionUtil.IfNullThrowException(v4navProperty, "Unable to locate property " + nodeIn.NavigationProperty.Name); return new CollectionNavigationNode((SingleResourceNode)nodeIn.Source.Accept(this), v4navProperty, pathExpr); }
internal static IEdmNavigationProperty ResolvePartnerPath(IEdmEntityType type, IEdmPathExpression path, IEdmModel model) { Debug.Assert(type != null); Debug.Assert(path != null); Debug.Assert(model != null); IEdmStructuredType currentType = type; IEdmProperty property = null; foreach (var segment in path.PathSegments) { if (currentType == null) { return(null); } if (segment.IndexOf('.') < 0) { property = currentType.FindProperty(segment); if (property == null) { return(null); } currentType = property.Type.Definition.AsElementType() as IEdmStructuredType; } else { var derivedType = model.FindDeclaredType(segment); if (derivedType == null || !derivedType.IsOrInheritsFrom(currentType)) { return(null); } currentType = derivedType as IEdmStructuredType; property = null; } } return(property != null ? property as IEdmNavigationProperty : null); }
/// <summary> /// Validates that a property with the specified name exists on a given structured type. /// The structured type can be null if no metadata is available. /// </summary> /// <param name="propertyName">The name of the property to validate.</param> /// <param name="owningStructuredType">The owning type of the property with name <paramref name="propertyName"/> /// or null if no metadata is available.</param> /// <returns>The <see cref="IEdmProperty"/> instance representing the property with name <paramref name="propertyName"/> /// or null if no metadata is available.</returns> internal static IEdmProperty ValidatePropertyDefined(string propertyName, IEdmStructuredType owningStructuredType) { Debug.Assert(!string.IsNullOrEmpty(propertyName), "!string.IsNullOrEmpty(propertyName)"); if (owningStructuredType == null) { return(null); } IEdmProperty property = owningStructuredType.FindProperty(propertyName); // verify that the property is declared if the type is not an open type. if (!owningStructuredType.IsOpen && property == null) { throw new ODataException(Strings.ValidationUtils_PropertyDoesNotExistOnType(propertyName, owningStructuredType.ODataFullName())); } return(property); }
/// <summary> /// Translates a v3 NavigationPropertySegment (TODO: EXAMPLE) into v4 NavigationPropertySegment /// </summary> /// <param name="segment">OData V3 NavigationPropertySegment</param> /// <returns>OData V4 NavigationPropertySegment</returns> public override ODataPathSegment Translate(Data.OData.Query.SemanticAst.NavigationPropertySegment segment) { // Look up corresponding V4 type in model IEdmStructuredType v4Type = v4model.GetV4Definition(segment.NavigationProperty.DeclaringType) as IEdmStructuredType; ExceptionUtil.IfNullThrowException(v4Type, "Unable to locate equivalent v4 type for declaring type: " + segment.NavigationProperty.DeclaringType.GetFullTypeName()); // Use corresponding V4 type to look up corresponding NavigationProperty IEdmNavigationProperty v4navigationProperty = v4Type.FindProperty(segment.NavigationProperty.Name) as IEdmNavigationProperty; ExceptionUtil.IfNullThrowException(v4navigationProperty, "Unable to locate equivalent v4 property for " + segment.NavigationProperty.Name); // Separately, look up navigation source (entity set) IEdmNavigationSource v4navigationSource = v4model.FindDeclaredNavigationSource(segment.EntitySet.Name); ExceptionUtil.IfNullThrowException(v4navigationSource, "Unable to locate navigation source for entity set: " + segment.EntitySet.Name); return(new NavigationPropertySegment(v4navigationProperty, v4navigationSource)); }
/// <summary> /// Resolve property from property name /// </summary> /// <param name="type">The declaring type.</param> /// <param name="propertyName">The property name.</param> /// <returns>The resolved <see cref="IEdmProperty"/></returns> public virtual IEdmProperty ResolveProperty(IEdmStructuredType type, string propertyName) { if (EnableCaseInsensitive) { var result = type.Properties() .Where(_ => string.Equals(propertyName, _.Name, StringComparison.OrdinalIgnoreCase)) .ToList(); if (result.Count == 1) { return(result.Single()); } else if (result.Count > 1) { throw new ODataException(Strings.UriParserMetadata_MultipleMatchingPropertiesFound(propertyName, type.FullTypeName())); } } return(type.FindProperty(propertyName)); }
/// <summary> /// Validates that a property with the specified name exists on a given structured type. /// The structured type can be null if no metadata is available. /// </summary> /// <param name="propertyName">The name of the property to validate.</param> /// <param name="owningStructuredType">The owning type of the property with name <paramref name="propertyName"/> /// or null if no metadata is available.</param> /// <param name="throwOnUndeclaredProperty">Flag indicating whether undeclared property on non open type should be prohibited.</param> /// <returns>The <see cref="IEdmProperty"/> instance representing the property with name <paramref name="propertyName"/> /// or null if no metadata is available.</returns> internal static IEdmProperty ValidatePropertyDefined( string propertyName, IEdmStructuredType owningStructuredType, bool throwOnUndeclaredProperty) { Debug.Assert(!string.IsNullOrEmpty(propertyName), "!string.IsNullOrEmpty(propertyName)"); if (owningStructuredType == null) { return(null); } IEdmProperty property = owningStructuredType.FindProperty(propertyName); if (throwOnUndeclaredProperty && !owningStructuredType.IsOpen && property == null) { throw new ODataException(Strings.ValidationUtils_PropertyDoesNotExistOnType(propertyName, owningStructuredType.FullTypeName())); } return(property); }
/// <summary> /// Compares two sets of structural properties (expected value in CSDL, actual as IEdmStructuredType). /// This can apply to both entity types and complex types. /// </summary> /// <param name="propertyElements">The CSDL element representing the properties.</param> /// <param name="modelType">The EDM model type to compare against.</param> private static void CompareStructuralProperties(IEnumerable <XElement> propertyElements, IEdmStructuredType modelType) { ExceptionUtilities.Assert(propertyElements.Count() == modelType.StructuralProperties().Count(), "Unexpected number of properties on type " + modelType.TestFullName()); foreach (var propertyElement in propertyElements) { var propertyName = propertyElement.GetAttributeValue("Name"); var propertyOnModel = modelType.FindProperty(propertyName) as IEdmStructuralProperty; ExceptionUtilities.Assert(propertyOnModel != null, "Failed to find structural property " + propertyName + " on type " + modelType.TestFullName()); CompareType(propertyElement, propertyOnModel.Type); // TODO: Enable this. // CompareTypeFacets(propertyElement, propertyOnModel.Type); string defaultValueString; if (propertyElement.TryGetAttributeValue("DefaultValue", out defaultValueString)) { ExceptionUtilities.Assert(string.Compare(defaultValueString, propertyOnModel.DefaultValueString) == 0, "Unexpected value for DefaultValue"); } else { ExceptionUtilities.Assert(string.IsNullOrEmpty(propertyOnModel.DefaultValueString), "Did not expect a value for DefaultValue property"); } } }
/// <summary> /// Validates that a property with the specified name exists on a given structured type. /// The structured type can be null if no metadata is available. /// </summary> /// <param name="propertyName">The name of the property to validate.</param> /// <param name="owningStructuredType">The owning type of the property with name <paramref name="propertyName"/> /// or null if no metadata is available.</param> /// <param name="undeclaredPropertyBehaviorKinds">Value of UndeclaredPropertyBehaviorKinds in message settings.</param> /// <returns>The <see cref="IEdmProperty"/> instance representing the property with name <paramref name="propertyName"/> /// or null if no metadata is available.</returns> internal static IEdmProperty ValidatePropertyDefined(string propertyName, IEdmStructuredType owningStructuredType, ODataUndeclaredPropertyBehaviorKinds undeclaredPropertyBehaviorKinds) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(!string.IsNullOrEmpty(propertyName), "!string.IsNullOrEmpty(propertyName)"); if (owningStructuredType == null) { return(null); } // .None / .LinkProperty bool throwErr = !undeclaredPropertyBehaviorKinds.HasFlag(ODataUndeclaredPropertyBehaviorKinds.IgnoreUndeclaredValueProperty) && !undeclaredPropertyBehaviorKinds.HasFlag(ODataUndeclaredPropertyBehaviorKinds.SupportUndeclaredValueProperty); IEdmProperty property = owningStructuredType.FindProperty(propertyName); // verify that the property is declared if the type is not an open type. if (throwErr && !owningStructuredType.IsOpen && property == null) { throw new ODataException(Strings.ValidationUtils_PropertyDoesNotExistOnType(propertyName, owningStructuredType.ODataFullName())); } return(property); }
/// <summary> /// Generates a dictionary with property name and property values specified in the skiptoken value. /// </summary> /// <param name="value">The skiptoken string value.</param> /// <param name="context">The <see cref="ODataQueryContext"/> which contains the <see cref="IEdmModel"/> and some type information</param> /// <returns>Dictionary with property name and property value in the skiptoken value.</returns> private static IDictionary <string, object> PopulatePropertyValuePairs(string value, ODataQueryContext context) { Contract.Assert(context != null); IDictionary <string, object> propertyValuePairs = new Dictionary <string, object>(); IList <string> keyValuesPairs = ParseValue(value, CommaDelimiter); IEdmStructuredType type = context.ElementType as IEdmStructuredType; Debug.Assert(type != null); foreach (string pair in keyValuesPairs) { string[] pieces = pair.Split(new char[] { propertyDelimiter }, 2); if (pieces.Length > 1 && !String.IsNullOrWhiteSpace(pieces[0])) { object propValue = null; IEdmTypeReference propertyType = null; IEdmProperty property = type.FindProperty(pieces[0]); if (property != null) { propertyType = property.Type; } propValue = ODataUriUtils.ConvertFromUriLiteral(pieces[1], ODataVersion.V401, context.Model, propertyType); propertyValuePairs.Add(pieces[0], propValue); } else { throw Error.InvalidOperation(SRResources.SkipTokenParseError); } } return(propertyValuePairs); }
private static bool TryBindAsDeclaredProperty(PathSegmentToken tokenIn, IEdmStructuredType edmType, out ODataPathSegment segment) { IEdmProperty prop = edmType.FindProperty(tokenIn.Identifier); if (prop == null) { segment = null; return(false); } if (prop.PropertyKind == EdmPropertyKind.Structural) { segment = new PropertySegment((IEdmStructuralProperty)prop); return(true); } if (prop.PropertyKind == EdmPropertyKind.Navigation) { segment = new NavigationPropertySegment((IEdmNavigationProperty)prop, null /*TODO set*/); return(true); } throw new ODataException(ODataErrorStrings.SelectExpandBinder_UnknownPropertyType(prop.Name)); }
internal static IEdmProperty ValidatePropertyDefined(string propertyName, IEdmStructuredType owningStructuredType) { if (owningStructuredType == null) { return null; } IEdmProperty property = owningStructuredType.FindProperty(propertyName); if (!owningStructuredType.IsOpen && (property == null)) { throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_PropertyDoesNotExistOnType(propertyName, owningStructuredType.ODataFullName())); } return property; }
private IEdmVocabularyAnnotatable ComputeTarget() { if (this.targetContext != null) { return(this.targetContext); } else { Debug.Assert(this.annotationsContext != null, "Annotation must either have a target context or annotations context"); string target = this.annotationsContext.Annotations.Target; string[] targetSegments = target.Split('/'); int targetSegmentsCount = targetSegments.Count(); IEdmEntityContainer container; if (targetSegmentsCount == 1) { string elementName = targetSegments[0]; IEdmSchemaType type = this.schema.FindType(elementName); if (type != null) { return(type); } IEdmValueTerm term = this.schema.FindValueTerm(elementName); if (term != null) { return(term); } IEdmFunction function = this.FindParameterizedFunction(elementName, this.Schema.FindFunctions, this.CreateAmbiguousFunction); if (function != null) { return(function); } container = this.schema.FindEntityContainer(elementName); if (container != null) { return(container); } return(new UnresolvedType(this.Schema.UnresolvedName(targetSegments[0]), this.Location)); } if (targetSegmentsCount == 2) { container = this.schema.FindEntityContainer(targetSegments[0]); if (container != null) { IEdmEntityContainerElement containerElement = container.FindEntitySet(targetSegments[1]); if (containerElement != null) { return(containerElement); } IEdmFunctionImport functionImport = this.FindParameterizedFunction(targetSegments[1], container.FindFunctionImports, this.CreateAmbiguousFunctionImport); if (functionImport != null) { return(functionImport); } return(new UnresolvedEntitySet(targetSegments[1], container, this.Location)); } IEdmStructuredType type = this.schema.FindType(targetSegments[0]) as IEdmStructuredType; if (type != null) { IEdmProperty property = type.FindProperty(targetSegments[1]); if (property != null) { return(property); } return(new UnresolvedProperty(type, targetSegments[1], this.Location)); } IEdmFunction function = this.FindParameterizedFunction(targetSegments[0], this.Schema.FindFunctions, this.CreateAmbiguousFunction); if (function != null) { IEdmFunctionParameter parameter = function.FindParameter(targetSegments[1]); if (parameter != null) { return(parameter); } return(new UnresolvedParameter(function, targetSegments[1], this.Location)); } return(new UnresolvedProperty(new UnresolvedEntityType(this.Schema.UnresolvedName(targetSegments[0]), this.Location), targetSegments[1], this.Location)); } if (targetSegmentsCount == 3) { container = this.Model.FindEntityContainer(targetSegments[0]); if (container != null) { IEdmFunctionImport functionImport = this.FindParameterizedFunction(targetSegments[1], container.FindFunctionImports, this.CreateAmbiguousFunctionImport); if (functionImport != null) { IEdmFunctionParameter parameter = functionImport.FindParameter(targetSegments[2]); if (parameter != null) { return(parameter); } return(new UnresolvedParameter(functionImport, targetSegments[1], this.Location)); } } } return(new BadElement(new EdmError[] { new EdmError(this.Location, EdmErrorCode.ImpossibleAnnotationsTarget, Edm.Strings.CsdlSemantics_ImpossibleAnnotationsTarget(target)) })); } }
/// <summary> /// Resolve property from property name /// </summary> /// <param name="type">The declaring type.</param> /// <param name="propertyName">The property name.</param> /// <returns>The resolved <see cref="IEdmProperty"/></returns> public virtual IEdmProperty ResolveProperty(IEdmStructuredType type, string propertyName) { if (EnableCaseInsensitive) { var result = type.Properties() .Where(_ => string.Equals(propertyName, _.Name, StringComparison.OrdinalIgnoreCase)) .ToList(); if (result.Count == 1) { return result.Single(); } else if (result.Count > 1) { throw new ODataException(Strings.UriParserMetadata_MultipleMatchingPropertiesFound(propertyName, type.FullTypeName())); } } return type.FindProperty(propertyName); }
private IEdmVocabularyAnnotatable ComputeTarget() { IEdmEntityContainer edmEntityContainer; if (this.targetContext == null) { string target = this.annotationsContext.Annotations.Target; char[] chrArray = new char[1]; chrArray[0] = '/'; string[] strArrays = target.Split(chrArray); int num = strArrays.Count <string>(); if (num != 1) { if (num != 2) { if (num == 3) { edmEntityContainer = this.Model.FindEntityContainer(strArrays[0]); if (edmEntityContainer != null) { IEdmEntityContainer edmEntityContainer1 = edmEntityContainer; IEdmFunctionImport edmFunctionImport = this.FindParameterizedFunction <IEdmFunctionImport>(strArrays[1], new Func <string, IEnumerable <IEdmFunctionImport> >(edmEntityContainer1.FindFunctionImports), new Func <IEnumerable <IEdmFunctionImport>, IEdmFunctionImport>(this.CreateAmbiguousFunctionImport)); if (edmFunctionImport != null) { IEdmFunctionParameter edmFunctionParameter = edmFunctionImport.FindParameter(strArrays[2]); if (edmFunctionParameter == null) { return(new UnresolvedParameter(edmFunctionImport, strArrays[1], base.Location)); } else { return(edmFunctionParameter); } } } } EdmError[] edmError = new EdmError[1]; edmError[0] = new EdmError(base.Location, EdmErrorCode.ImpossibleAnnotationsTarget, Strings.CsdlSemantics_ImpossibleAnnotationsTarget(target)); return(new BadElement(edmError)); } else { edmEntityContainer = this.schema.FindEntityContainer(strArrays[0]); if (edmEntityContainer == null) { IEdmStructuredType edmStructuredType = this.schema.FindType(strArrays[0]) as IEdmStructuredType; if (edmStructuredType == null) { IEdmFunction edmFunction = this.FindParameterizedFunction <IEdmFunction>(strArrays[0], new Func <string, IEnumerable <IEdmFunction> >(this.Schema.FindFunctions), new Func <IEnumerable <IEdmFunction>, IEdmFunction>(this.CreateAmbiguousFunction)); if (edmFunction == null) { return(new UnresolvedProperty(new UnresolvedEntityType(this.Schema.UnresolvedName(strArrays[0]), base.Location), strArrays[1], base.Location)); } else { IEdmFunctionParameter edmFunctionParameter1 = edmFunction.FindParameter(strArrays[1]); if (edmFunctionParameter1 == null) { return(new UnresolvedParameter(edmFunction, strArrays[1], base.Location)); } else { return(edmFunctionParameter1); } } } else { IEdmProperty edmProperty = edmStructuredType.FindProperty(strArrays[1]); if (edmProperty == null) { return(new UnresolvedProperty(edmStructuredType, strArrays[1], base.Location)); } else { return(edmProperty); } } } else { IEdmEntityContainerElement edmEntityContainerElement = edmEntityContainer.FindEntitySet(strArrays[1]); if (edmEntityContainerElement == null) { IEdmEntityContainer edmEntityContainer2 = edmEntityContainer; IEdmFunctionImport edmFunctionImport1 = this.FindParameterizedFunction <IEdmFunctionImport>(strArrays[1], new Func <string, IEnumerable <IEdmFunctionImport> >(edmEntityContainer2.FindFunctionImports), new Func <IEnumerable <IEdmFunctionImport>, IEdmFunctionImport>(this.CreateAmbiguousFunctionImport)); if (edmFunctionImport1 == null) { return(new UnresolvedEntitySet(strArrays[1], edmEntityContainer, base.Location)); } else { return(edmFunctionImport1); } } else { return(edmEntityContainerElement); } } } } else { string str = strArrays[0]; IEdmSchemaType edmSchemaType = this.schema.FindType(str); if (edmSchemaType == null) { IEdmValueTerm edmValueTerm = this.schema.FindValueTerm(str); if (edmValueTerm == null) { IEdmFunction edmFunction1 = this.FindParameterizedFunction <IEdmFunction>(str, new Func <string, IEnumerable <IEdmFunction> >(this.Schema.FindFunctions), new Func <IEnumerable <IEdmFunction>, IEdmFunction>(this.CreateAmbiguousFunction)); if (edmFunction1 == null) { edmEntityContainer = this.schema.FindEntityContainer(str); if (edmEntityContainer == null) { return(new UnresolvedType(this.Schema.UnresolvedName(strArrays[0]), base.Location)); } else { return(edmEntityContainer); } } else { return(edmFunction1); } } else { return(edmValueTerm); } } else { return(edmSchemaType); } } } else { return(this.targetContext); } }
private void ValidateAnnotationWithFewerPropertyThanType(IEdmModel model, IEdmStructuredType actualType, IEnumerable<IEdmPropertyConstructor> annotationProperties) { foreach (var annotationProperty in annotationProperties) { var annotationName = annotationProperty.Name; var actualProperty = actualType.FindProperty(annotationName); Assert.IsNotNull(actualProperty, "Invalid property name."); Action<IEdmModel, IEdmStructuredType, IEnumerable<IEdmPropertyConstructor>> validateAnnotation = (m, t, l) => this.ValidateAnnotationWithFewerPropertyThanType(m, t, l); ValidateAnnotationProperty(model, actualProperty, annotationProperty, validateAnnotation); } }
private void ValidateAnnotationWithExactPropertyAsType(IEdmModel model, IEdmStructuredType actualType, IEnumerable<IEdmPropertyConstructor> annotationProperties) { Assert.AreEqual(actualType.Properties().Count(), annotationProperties.Count(), "Annotation does not have the same count of properties as it's declared type."); foreach (var annotationProperty in annotationProperties) { var annotationName = annotationProperty.Name; var actualProperty = actualType.FindProperty(annotationName); Assert.IsNotNull(actualProperty, "Invalid property name."); Action<IEdmModel, IEdmStructuredType, IEnumerable<IEdmPropertyConstructor>> validateAnnotation = (m, t, l) => this.ValidateAnnotationWithExactPropertyAsType(m, t, l); ValidateAnnotationProperty(model, actualProperty, annotationProperty, validateAnnotation); } }
private IEdmVocabularyAnnotatable ComputeTarget() { if (this.targetContext != null) { return(this.targetContext); } else { Debug.Assert(this.annotationsContext != null, "Annotation must either have a target context or annotations context"); string target = this.annotationsContext.Annotations.Target; string[] targetSegments = target.Split('/'); int targetSegmentsCount = targetSegments.Count(); IEdmEntityContainer container; if (targetSegmentsCount == 1) { string elementName = targetSegments[0]; IEdmSchemaType type = this.schema.FindType(elementName); if (type != null) { return(type); } IEdmValueTerm term = this.schema.FindValueTerm(elementName); if (term != null) { return(term); } IEdmOperation operation = this.FindParameterizedOperation(elementName, this.Schema.FindOperations, this.CreateAmbiguousOperation); if (operation != null) { return(operation); } container = this.schema.FindEntityContainer(elementName); if (container != null) { return(container); } return(new UnresolvedType(this.Schema.UnresolvedName(targetSegments[0]), this.Location)); } if (targetSegmentsCount == 2) { container = this.schema.FindEntityContainer(targetSegments[0]); if (container != null) { IEdmEntityContainerElement containerElement = container.FindEntitySetExtended(targetSegments[1]); if (containerElement != null) { return(containerElement); } IEdmOperationImport operationImport = this.FindParameterizedOperationImport(targetSegments[1], container.FindOperationImportsExtended, this.CreateAmbiguousOperationImport); if (operationImport != null) { return(operationImport); } return(new UnresolvedEntitySet(targetSegments[1], container, this.Location)); } IEdmStructuredType type = this.schema.FindType(targetSegments[0]) as IEdmStructuredType; if (type != null) { IEdmProperty property = type.FindProperty(targetSegments[1]); if (property != null) { return(property); } return(new UnresolvedProperty(type, targetSegments[1], this.Location)); } IEdmOperation operation = this.FindParameterizedOperation(targetSegments[0], this.Schema.FindOperations, this.CreateAmbiguousOperation); if (operation != null) { IEdmOperationParameter parameter = operation.FindParameter(targetSegments[1]); if (parameter != null) { return(parameter); } return(new UnresolvedParameter(operation, targetSegments[1], this.Location)); } return(new UnresolvedProperty(new UnresolvedEntityType(this.Schema.UnresolvedName(targetSegments[0]), this.Location), targetSegments[1], this.Location)); } if (targetSegmentsCount == 3) { // The only valid target with three segments is a function parameter. string containerName = targetSegments[0]; string operationName = targetSegments[1]; string parameterName = targetSegments[2]; container = this.Model.FindEntityContainer(containerName); if (container != null) { IEdmOperationImport operationImport = this.FindParameterizedOperationImport(operationName, container.FindOperationImportsExtended, this.CreateAmbiguousOperationImport); if (operationImport != null) { IEdmOperationParameter parameter = operationImport.Operation.FindParameter(parameterName); if (parameter != null) { return(parameter); } return(new UnresolvedParameter(operationImport.Operation, parameterName, this.Location)); } } string qualifiedOperationName = containerName + "/" + operationName; UnresolvedOperation unresolvedOperation = new UnresolvedOperation(qualifiedOperationName, Edm.Strings.Bad_UnresolvedOperation(qualifiedOperationName), this.Location); return(new UnresolvedParameter(unresolvedOperation, parameterName, this.Location)); } return(new BadElement(new EdmError[] { new EdmError(this.Location, EdmErrorCode.ImpossibleAnnotationsTarget, Edm.Strings.CsdlSemantics_ImpossibleAnnotationsTarget(target)) })); } }
/// <summary> /// Generate an expand item (and a select item for the implicit nav prop if necessary) based on an ExpandTermToken /// </summary> /// <param name="tokenIn">the expandTerm token to visit</param> /// <returns>the expand item for this expand term token.</returns> private ExpandedNavigationSelectItem GenerateExpandItem(ExpandTermToken tokenIn) { ExceptionUtils.CheckArgumentNotNull(tokenIn, "tokenIn"); // ensure that we're always dealing with proper V4 syntax if (tokenIn.PathToNavProp.NextToken != null && !tokenIn.PathToNavProp.IsNamespaceOrContainerQualified()) { throw new ODataException(ODataErrorStrings.ExpandItemBinder_TraversingMultipleNavPropsInTheSamePath); } PathSegmentToken currentToken = tokenIn.PathToNavProp; IEdmStructuredType currentLevelEntityType = this.EdmType; List <ODataPathSegment> pathSoFar = new List <ODataPathSegment>(); PathSegmentToken firstNonTypeToken = currentToken; if (currentToken.IsNamespaceOrContainerQualified()) { pathSoFar.AddRange(SelectExpandPathBinder.FollowTypeSegments(currentToken, this.Model, this.Settings.SelectExpandLimit, ref currentLevelEntityType, out firstNonTypeToken)); } IEdmProperty edmProperty = currentLevelEntityType.FindProperty(firstNonTypeToken.Identifier); if (edmProperty == null) { throw new ODataException(ODataErrorStrings.MetadataBinder_PropertyNotDeclared(currentLevelEntityType.ODataFullName(), currentToken.Identifier)); } IEdmNavigationProperty currentNavProp = edmProperty as IEdmNavigationProperty; if (currentNavProp == null) { throw new ODataException(ODataErrorStrings.ExpandItemBinder_PropertyIsNotANavigationProperty(currentToken.Identifier, currentLevelEntityType.ODataFullName())); } if (firstNonTypeToken.NextToken != null) { // lastly... make sure that, since we're on a NavProp, that the next token isn't null. throw new ODataException(ODataErrorStrings.ExpandItemBinder_TraversingMultipleNavPropsInTheSamePath); } pathSoFar.Add(new NavigationPropertySegment(currentNavProp, /*entitySet*/ null)); ODataExpandPath pathToNavProp = new ODataExpandPath(pathSoFar); SelectExpandClause subSelectExpand; if (tokenIn.ExpandOption != null) { subSelectExpand = this.GenerateSubExpand(currentNavProp, tokenIn); } else { subSelectExpand = BuildDefaultSubExpand(); } subSelectExpand = this.DecorateExpandWithSelect(subSelectExpand, currentNavProp, tokenIn.SelectOption); IEdmNavigationSource targetNavigationSource = null; if (this.NavigationSource != null) { targetNavigationSource = this.NavigationSource.FindNavigationTarget(currentNavProp); } // call MetadataBinder to build the filter clause FilterClause filterOption = null; if (tokenIn.FilterOption != null) { MetadataBinder binder = this.BuildNewMetadataBinder(targetNavigationSource); FilterBinder filterBinder = new FilterBinder(binder.Bind, binder.BindingState); filterOption = filterBinder.BindFilter(tokenIn.FilterOption); } // call MetadataBinder again to build the orderby clause OrderByClause orderbyOption = null; if (tokenIn.OrderByOptions != null) { MetadataBinder binder = this.BuildNewMetadataBinder(targetNavigationSource); OrderByBinder orderByBinder = new OrderByBinder(binder.Bind); orderbyOption = orderByBinder.BindOrderBy(binder.BindingState, tokenIn.OrderByOptions); } LevelsClause levelsOption = this.ParseLevels(tokenIn.LevelsOption, this.EdmType, currentNavProp); SearchClause searchOption = null; if (tokenIn.SearchOption != null) { MetadataBinder binder = this.BuildNewMetadataBinder(targetNavigationSource); SearchBinder searchBinder = new SearchBinder(binder.Bind); searchOption = searchBinder.BindSearch(tokenIn.SearchOption); } return(new ExpandedNavigationSelectItem(pathToNavProp, targetNavigationSource, filterOption, orderbyOption, tokenIn.TopOption, tokenIn.SkipOption, tokenIn.CountQueryOption, levelsOption, searchOption, subSelectExpand)); }
/// <summary> /// Validates that a property with the specified name exists on a given structured type. /// The structured type can be null if no metadata is available. /// </summary> /// <param name="propertyName">The name of the property to validate.</param> /// <param name="owningStructuredType">The owning type of the property with name <paramref name="propertyName"/> /// or null if no metadata is available.</param> /// <param name="throwOnMissingProperty">Whether throw exception on missing property.</param> /// <returns>The <see cref="IEdmProperty"/> instance representing the property with name <paramref name="propertyName"/> /// or null if no metadata is available.</returns> internal static IEdmProperty ValidatePropertyDefined( string propertyName, IEdmStructuredType owningStructuredType, bool throwOnMissingProperty = true) { Debug.Assert(!string.IsNullOrEmpty(propertyName), "!string.IsNullOrEmpty(propertyName)"); if (owningStructuredType == null) { return null; } IEdmProperty property = owningStructuredType.FindProperty(propertyName); // verify that the property is declared if the type is not an open type. if (throwOnMissingProperty && !owningStructuredType.IsOpen && property == null) { throw new ODataException(Strings.ValidationUtils_PropertyDoesNotExistOnType(propertyName, owningStructuredType.ODataFullName())); } return property; }
/// <summary> /// Finds a defined property from the model if one is available. /// The structured type can be null if no metadata is available. /// </summary> /// <param name="propertyName">The name of the property to find.</param> /// <param name="owningStructuredType">The owning type of the property with name <paramref name="propertyName"/> /// or null if no metadata is available.</param> /// <returns>The <see cref="IEdmProperty"/> instance representing the property with name <paramref name="propertyName"/> /// or null if no metadata is available.</returns> internal static IEdmProperty FindDefinedProperty(string propertyName, IEdmStructuredType owningStructuredType) { Debug.Assert(!string.IsNullOrEmpty(propertyName), "!string.IsNullOrEmpty(propertyName)"); if (owningStructuredType == null) { return null; } IEdmProperty property = owningStructuredType.FindProperty(propertyName); return property; }
private static void CompareMembers(IEdmStructuredType edmEdmType, IEdmStructuredType dataWebEdmType, bool isReflectionBasedProvider, out int totalNavProps) { // find the number of nav properties on this type (not the base type). This will help us to determine how many associations // be generated totalNavProps = edmEdmType.DeclaredProperties.OfType<IEdmNavigationProperty>().Count(); AstoriaTestLog.IsTrue(edmEdmType.DeclaredProperties.Count() == dataWebEdmType.DeclaredProperties.Count(), "Number of members must match"); foreach (IEdmProperty member1 in edmEdmType.DeclaredProperties) { IEdmProperty member2 = dataWebEdmType.FindProperty(member1.Name); AstoriaTestLog.IsNotNull(member2); // WCF DS server will always write DateTimeOffset as the data type, if the backend model has DateTime as the data type string edmMemberTypeName = member1.Type.FullName(); if (edmMemberTypeName == "Edm.DateTime") { AstoriaTestLog.IsTrue(member2.Type.FullName() == "Edm.DateTimeOffset", "For DateTime properties in the model, we should generate"); } else { AstoriaTestLog.IsTrue(edmMemberTypeName == member2.Type.FullName(), "Type must match"); } AstoriaTestLog.IsTrue(member1.Type.IsNullable == member2.Type.IsNullable, "nullability must match"); // TODO: if its a navigation, compare referential constraint! } }
/// <summary> /// Finds a defined property from the model if one is available. /// The structured type can be null if no metadata is available. /// </summary> /// <param name="propertyName">The name of the property to find.</param> /// <param name="owningStructuredType">The owning type of the property with name <paramref name="propertyName"/> /// or null if no metadata is available.</param> /// <param name="messageReaderSettings">The message reader settings being used.</param> /// <returns>The <see cref="IEdmProperty"/> instance representing the property with name <paramref name="propertyName"/> /// or null if no metadata is available.</returns> internal static IEdmProperty FindDefinedProperty(string propertyName, IEdmStructuredType owningStructuredType, ODataMessageReaderSettings messageReaderSettings) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(!string.IsNullOrEmpty(propertyName), "!string.IsNullOrEmpty(propertyName)"); Debug.Assert(messageReaderSettings != null, "messageReaderSettings != null"); if (owningStructuredType == null) { return null; } IEdmProperty property = owningStructuredType.FindProperty(propertyName); if (property == null && owningStructuredType.IsOpen) { if (messageReaderSettings.UndeclaredPropertyBehaviorKinds != ODataUndeclaredPropertyBehaviorKinds.None) { throw new ODataException(Strings.ReaderValidationUtils_UndeclaredPropertyBehaviorKindSpecifiedForOpenType(propertyName, owningStructuredType.ODataFullName())); } } return property; }