internal static bool TryAssertCollectionAsType(this IEdmCollectionExpression expression, IEdmTypeReference type, out IEnumerable <EdmError> discoveredErrors) { IEnumerable <EdmError> edmErrors = null; bool flag; if (type.IsCollection()) { IEdmTypeReference edmTypeReference = type.AsCollection().ElementType(); bool flag1 = true; List <EdmError> edmErrors1 = new List <EdmError>(); foreach (IEdmExpression element in expression.Elements) { if (!element.TryAssertType(edmTypeReference, out edmErrors)) { flag = false; } else { flag = flag1; } flag1 = flag; edmErrors1.AddRange(edmErrors); } discoveredErrors = edmErrors1; return(flag1); } else { EdmError[] edmError = new EdmError[1]; edmError[0] = new EdmError(expression.Location(), EdmErrorCode.CollectionExpressionNotValidForNonCollectionType, Strings.EdmModel_Validator_Semantic_CollectionExpressionNotValidForNonCollectionType); discoveredErrors = edmError; return(false); } }
public void EnumPropertyWithConcurrencyToken_SetsVocabuaryAnnotaion() { // Arrange var builder = ODataModelBuilderMocks.GetModelBuilderMock <ODataModelBuilder>().Add_Color_EnumType(); var entityTypeConfiguration = builder.EntityType <EntityTypeWithEnumTypePropertyTestModel>(); entityTypeConfiguration.EnumProperty(c => c.RequiredColor).IsOptional().IsConcurrencyToken(); builder.EntitySet <EntityTypeWithEnumTypePropertyTestModel>("EnumEntities"); // Act var model = builder.GetEdmModel(); // Assert var entityset = model.FindDeclaredEntitySet("EnumEntities"); Assert.NotNull(entityset); var annotations = model.FindVocabularyAnnotations <IEdmValueAnnotation>(entityset, CoreVocabularyModel.ConcurrencyTerm); IEdmValueAnnotation concurrencyAnnotation = Assert.Single(annotations); IEdmCollectionExpression properties = concurrencyAnnotation.Value as IEdmCollectionExpression; Assert.NotNull(properties); Assert.Equal(1, properties.Elements.Count()); var element = properties.Elements.First() as IEdmPathExpression; Assert.NotNull(element); string path = Assert.Single(element.Path); Assert.Equal("RequiredColor", path); }
public void GetEdmModel_PropertyWithETag_IsConcurrencyToken_HasVocabularyAnnotation() { // Arrange ODataModelBuilder builder = new ODataModelBuilder(); EntityTypeConfiguration <Customer> customer = builder.EntityType <Customer>(); customer.HasKey(c => c.Id); customer.Property(c => c.Id); customer.Property(c => c.Name).IsConcurrencyToken(); builder.EntitySet <Customer>("Customers"); // Act IEdmModel model = builder.GetEdmModel(); // Assert var customers = model.FindDeclaredEntitySet("Customers"); Assert.NotNull(customers); var annotations = model.FindVocabularyAnnotations <IEdmVocabularyAnnotation>(customers, CoreVocabularyModel.ConcurrencyTerm); IEdmVocabularyAnnotation concurrencyAnnotation = Assert.Single(annotations); IEdmCollectionExpression properties = concurrencyAnnotation.Value as IEdmCollectionExpression; Assert.NotNull(properties); Assert.Single(properties.Elements); var element = properties.Elements.First() as IEdmPathExpression; Assert.NotNull(element); string path = Assert.Single(element.PathSegments); Assert.Equal("Name", path); }
private static IList <NavigationPropertyRestriction> GetRestrictedProperties(IEdmRecordExpression record) { if (record != null && record.Properties != null) { IEdmPropertyConstructor property = record.Properties.FirstOrDefault(p => p.Name == "RestrictedProperties"); if (property != null) { IEdmCollectionExpression value = property.Value as IEdmCollectionExpression; if (value != null && value.Elements != null) { IList <NavigationPropertyRestriction> restrictedProperties = new List <NavigationPropertyRestriction>(); foreach (var item in value.Elements.OfType <IEdmRecordExpression>()) { NavigationPropertyRestriction restriction = new NavigationPropertyRestriction(); restriction.Navigability = item.GetEnum <NavigationType>("Navigability"); restriction.NavigationProperty = item.GetPropertyPath("NavigationProperty"); restrictedProperties.Add(restriction); } if (restrictedProperties.Any()) { return(restrictedProperties); } } } } return(null); }
/// <summary> /// Create the corresponding Authorization object. /// </summary> /// <param name="record">The input record.</param> /// <returns>The created <see cref="Authorization"/> object.</returns> public static IEnumerable <Authorization> GetAuthorizations(this IEdmModel model, IEdmVocabularyAnnotatable target) { Utils.CheckArgumentNull(model, nameof(model)); Utils.CheckArgumentNull(target, nameof(target)); return(GetOrAddCached(model, target, AuthorizationConstants.Authorizations, () => { IEdmTerm term = model.FindTerm(AuthorizationConstants.Authorizations); if (term != null) { IEdmVocabularyAnnotation annotation = model.FindVocabularyAnnotations <IEdmVocabularyAnnotation>(target, term).FirstOrDefault(); if (annotation != null && annotation.Value != null && annotation.Value.ExpressionKind == EdmExpressionKind.Collection) { IEdmCollectionExpression collection = (IEdmCollectionExpression)annotation.Value; if (collection.Elements != null) { return collection.Elements.Select(e => { Debug.Assert(e.ExpressionKind == EdmExpressionKind.Record); IEdmRecordExpression recordExpression = (IEdmRecordExpression)e; Authorization auth = Authorization.CreateAuthorization(recordExpression); return auth; }); } } } return null; })); }
/// <summary> /// Get the collection of property path from the record using the given property name. /// </summary> /// <param name="record">The record expression.</param> /// <param name="propertyName">The property name.</param> /// <returns>The collection of property path or null.</returns> public static IList <string> GetCollectionPropertyPath(this IEdmRecordExpression record, string propertyName) { Utils.CheckArgumentNull(record, nameof(record)); Utils.CheckArgumentNull(propertyName, nameof(propertyName)); if (record.Properties != null) { IEdmPropertyConstructor property = record.Properties.FirstOrDefault(e => e.Name == propertyName); if (property != null) { IEdmCollectionExpression value = property.Value as IEdmCollectionExpression; if (value != null && value.Elements != null) { IList <string> properties = new List <string>(); foreach (var a in value.Elements.Select(e => e as IEdmPathExpression)) { properties.Add(a.Path); } if (properties.Any()) { return(properties); } } } } return(null); }
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); }
public async Task ModelBuilderTest() { // Arrange string expectMetadata = "<EntitySet Name=\"ETagUntypedCustomers\" EntityType=\"NS.Customer\">\r\n" + " <Annotation Term=\"Org.OData.Core.V1.OptimisticConcurrency\">\r\n" + " <Collection>\r\n" + " <PropertyPath>Name</PropertyPath>\r\n" + " </Collection>\r\n" + " </Annotation>\r\n" + " </EntitySet>"; // Remove indentation expectMetadata = Regex.Replace(expectMetadata, @"\r\n\s*<", @"<"); HttpClient client = CreateClient(); string requestUri = "odata/$metadata"; // Act HttpResponseMessage response = await client.GetAsync(requestUri); // Assert var content = await response.Content.ReadAsStringAsync(); Assert.Contains(expectMetadata, content); var stream = await response.Content.ReadAsStreamAsync(); IODataResponseMessage message = new ODataMessageWrapper(stream, response.Content.Headers); var reader = new ODataMessageReader(message); var edmModel = reader.ReadMetadataDocument(); Assert.NotNull(edmModel); var etagCustomers = edmModel.FindDeclaredEntitySet("ETagUntypedCustomers"); Assert.NotNull(etagCustomers); var annotations = edmModel.FindDeclaredVocabularyAnnotations(etagCustomers); IEdmVocabularyAnnotation annotation = Assert.Single(annotations); Assert.NotNull(annotation); Assert.Same(CoreVocabularyModel.ConcurrencyTerm, annotation.Term); Assert.Same(etagCustomers, annotation.Target); IEdmVocabularyAnnotation valueAnnotation = annotation as IEdmVocabularyAnnotation; Assert.NotNull(valueAnnotation); Assert.NotNull(valueAnnotation.Value); IEdmCollectionExpression collection = valueAnnotation.Value as IEdmCollectionExpression; Assert.NotNull(collection); Assert.Equal(new[] { "Name" }, collection.Elements.Select(e => ((IEdmPathExpression)e).PathSegments.Single())); }
private IEnumerable <object> ParseRecordCollection(IEdmCollectionExpression collectionExpression) { var records = new List <ExpandoObject>(); foreach (IEdmRecordExpression recordExpression in collectionExpression.Elements) { records.Add(ParseRecordProperties(recordExpression)); } return(records); }
/// <summary> /// Gets the collection of Org.OData.Core.V1.HttpRequest for a given <see cref="IEdmVocabularyAnnotatable"/>. /// </summary> /// <param name="target">The target.</param> /// <returns>The collection of Org.OData.Core.V1.HttpRequest</returns> public IEnumerable <HttpRequest> GetHttpRequests(IEdmVocabularyAnnotatable target) { Utils.CheckArgumentNull(target, nameof(target)); if (Term == null) { return(null); } // Search the cache. if (_requests.TryGetValue(target, out IList <HttpRequest> value)) { return(value); } IEdmVocabularyAnnotation annotation = Model.GetVocabularyAnnotation(target, Term); if (annotation == null) { IEdmNavigationSource navigationSource = target as IEdmNavigationSource; // if not, search the entity type. if (navigationSource != null) { IEdmEntityType entityType = navigationSource.EntityType(); annotation = Model.GetVocabularyAnnotation(entityType, Term); } } if (annotation == null || annotation.Value == null || annotation.Value.ExpressionKind != EdmExpressionKind.Collection) { _requests[target] = null; return(null); } IEdmCollectionExpression collection = (IEdmCollectionExpression)annotation.Value; var httpRequests = new List <HttpRequest>(); foreach (var item in collection.Elements) { IEdmRecordExpression record = (IEdmRecordExpression)item; HttpRequest newRequest = new HttpRequest(); newRequest.Init(record); httpRequests.Add(newRequest); } _requests[target] = httpRequests; return(httpRequests); }
public void ModelBuilderTest() { const string expectMetadata = " <EntitySet Name=\"ETagUntypedCustomers\" EntityType=\"NS.Customer\">\r\n" + " <Annotation Term=\"Org.OData.Core.V1.OptimisticConcurrency\">\r\n" + " <Collection>\r\n" + " <PropertyPath>Name</PropertyPath>\r\n" + " </Collection>\r\n" + " </Annotation>\r\n" + " </EntitySet>"; string requestUri = string.Format("{0}/odata/$metadata", this.BaseAddress); HttpResponseMessage response = this.Client.GetAsync(requestUri).Result; var content = response.Content.ReadAsStringAsync().Result; Assert.Contains(expectMetadata, content); var stream = response.Content.ReadAsStreamAsync().Result; IODataResponseMessage message = new ODataMessageWrapper(stream, response.Content.Headers); var reader = new ODataMessageReader(message); var edmModel = reader.ReadMetadataDocument(); Assert.NotNull(edmModel); var etagCustomers = edmModel.FindDeclaredEntitySet("ETagUntypedCustomers"); Assert.NotNull(etagCustomers); var annotations = edmModel.FindDeclaredVocabularyAnnotations(etagCustomers); IEdmVocabularyAnnotation annotation = Assert.Single(annotations); Assert.NotNull(annotation); Assert.Same(CoreVocabularyModel.ConcurrencyTerm, annotation.Term); Assert.Same(etagCustomers, annotation.Target); IEdmValueAnnotation valueAnnotation = annotation as IEdmValueAnnotation; Assert.NotNull(valueAnnotation); Assert.NotNull(valueAnnotation.Value); IEdmCollectionExpression collection = valueAnnotation.Value as IEdmCollectionExpression; Assert.NotNull(collection); Assert.Equal(new[] { "Name" }, collection.Elements.Select(e => ((IEdmPathExpression)e).Path.Single())); }
private void ParsePropertyCollection(OdcmObject odcmObject, IEdmCollectionExpression collectionExpression, string annotationTerm) { foreach (IEdmRecordExpression recordExpression in collectionExpression.Elements) { var pathExpression = (IEdmPathExpression)recordExpression.Properties .First(p => p.Value is IEdmPathExpression) .Value; var odcmProperty = SetPathCapability(odcmObject, pathExpression, annotationTerm); foreach (var propertyConstructor in recordExpression.Properties.Where(p => !(p.Value is IEdmPathExpression))) { TryParseCapability(odcmProperty, propertyConstructor.Value, annotationTerm + "/" + propertyConstructor.Name); } } }
/// <summary> /// Get the collection of <typeparamref name="T"/> from the record using the given property name. /// </summary> /// <param name="record">The record expression.</param> /// <param name="propertyName">The property name.</param> /// <param name="elementFunc">The element func.</param> /// <returns>The collection of string or null.</returns> public static IEnumerable <T> GetCollection <T>(this IEdmRecordExpression record, string propertyName, Func <IEdmExpression, T> elementFunc) { Utils.CheckArgumentNull(record, nameof(record)); Utils.CheckArgumentNull(propertyName, nameof(propertyName)); IEdmPropertyConstructor property = record.Properties.FirstOrDefault(e => e.Name == propertyName); if (property != null) { IEdmCollectionExpression collection = property.Value as IEdmCollectionExpression; if (collection != null && collection.Elements != null) { return(collection.Elements.Select(e => elementFunc(e))); } } return(null); }
/// <summary> /// Gets the collection of string for a target annotatable. /// </summary> /// <param name="model">The model referenced to.</param> /// <param name="target">The target annotatable to find annotation.</param> /// <param name="term">The target annotatable to find annotation.</param> /// <returns>Null or a collection string of qualified type name.</returns> public static IEnumerable <string> GetVocabularyStringCollection(this IEdmModel model, IEdmVocabularyAnnotatable target, IEdmTerm term) { EdmUtil.CheckArgumentNull(model, "model"); EdmUtil.CheckArgumentNull(target, "target"); EdmUtil.CheckArgumentNull(target, "term"); IEdmVocabularyAnnotation annotation = model.FindVocabularyAnnotations <IEdmVocabularyAnnotation>(target, term).FirstOrDefault(); if (annotation != null) { IEdmCollectionExpression collectionExpression = annotation.Value as IEdmCollectionExpression; if (collectionExpression != null && collectionExpression.Elements != null) { return(collectionExpression.Elements.OfType <IEdmStringConstantExpression>().Select(e => e.Value)); } } return(Enumerable.Empty <string>()); }
private void ParseCollection(OdcmObject odcmObject, IEdmCollectionExpression collectionExpression, string annotationTerm) { if (!collectionExpression.Elements.Any()) { return; } var elementExpression = collectionExpression.Elements.First(); var recordExpression = elementExpression as IEdmRecordExpression; if (recordExpression != null) { if (recordExpression.Properties.Count(p => p.Value is IEdmPathExpression) == 1) { // We assume that if a collection element is a record with a single path expression, the rest // of record properties should be associated with this path expression // (e.g. NavigationRestrictions/RestrictedProperties). ParsePropertyCollection(odcmObject, collectionExpression, annotationTerm); } else { var records = ParseRecordCollection(collectionExpression); SetListCapability(odcmObject, records, annotationTerm); } } else if (elementExpression is IEdmStringConstantExpression) { var strings = collectionExpression.Elements.Select(e => (e as IEdmStringConstantExpression).Value); SetListCapability(odcmObject, strings, annotationTerm); } else if (elementExpression is IEdmPathExpression) { foreach (IEdmPathExpression expression in collectionExpression.Elements) { SetPathCapability(odcmObject, expression, annotationTerm); } } else { Logger.Warn($"Unsupported collection of kind {elementExpression.ExpressionKind.ToString()} for Term \"{annotationTerm}\""); } }
private XObject GenerateCollectionExpression(XNamespace ns, IEdmCollectionExpression collection) { var collectionElements = new XElement(ns.GetName("Collection")); foreach (var element in collection.Elements) { var elementValue = GenerateValueExpression(ns, element); if (elementValue is XAttribute) { var collectionElement = new XElement(ns.GetName(((XAttribute)elementValue).Name.ToString())); collectionElement.Add(((XAttribute)elementValue).Value); collectionElements.Add(collectionElement); } else { collectionElements.Add(elementValue); } } return(collectionElements); }
/// <summary> /// Gets the Org.OData.Core.V1.AcceptableMediaTypes /// </summary> /// <param name="model">The Edm model.</param> /// <param name="target">The vocabulary annotatable target.</param> /// <returns>null or the collection of media type.</returns> internal static IList <string> GetAcceptableMediaTypes(this IEdmModel model, IEdmVocabularyAnnotatable target) { if (model == null) { throw Error.ArgumentNull(nameof(model)); } if (target == null) { throw Error.ArgumentNull(nameof(target)); } IList <string> mediaTypes = null; var annotations = model.FindVocabularyAnnotations <IEdmVocabularyAnnotation>(target, CoreVocabularyModel.AcceptableMediaTypesTerm); IEdmVocabularyAnnotation annotation = annotations.FirstOrDefault(); if (annotation != null) { IEdmCollectionExpression properties = annotation.Value as IEdmCollectionExpression; if (properties != null) { mediaTypes = new List <string>(); foreach (var element in properties.Elements) { IEdmStringConstantExpression elementValue = element as IEdmStringConstantExpression; if (elementValue != null) { mediaTypes.Add(elementValue.Value); } } } } if (mediaTypes == null || mediaTypes.Count == 0) { return(null); } return(mediaTypes); }
private static IEnumerable <IDictionary <string, IEdmPathExpression> > GetDeclaredAlternateKeysForType(IEdmModel model, IEdmEntityType type, IEdmTerm term) { IEdmVocabularyAnnotation annotationValue = model.FindVocabularyAnnotations <IEdmVocabularyAnnotation>(type, term).FirstOrDefault(); if (annotationValue != null) { List <IDictionary <string, IEdmPathExpression> > declaredAlternateKeys = new List <IDictionary <string, IEdmPathExpression> >(); IEdmCollectionExpression keys = annotationValue.Value as IEdmCollectionExpression; foreach (IEdmRecordExpression key in keys.Elements.OfType <IEdmRecordExpression>()) { var edmPropertyConstructor = key.Properties.FirstOrDefault(e => e.Name == "Key"); if (edmPropertyConstructor != null) { IEdmCollectionExpression collectionExpression = edmPropertyConstructor.Value as IEdmCollectionExpression; IDictionary <string, IEdmPathExpression> alternateKey = new Dictionary <string, IEdmPathExpression>(); foreach (IEdmRecordExpression propertyRef in collectionExpression.Elements.OfType <IEdmRecordExpression>()) { var aliasProp = propertyRef.Properties.FirstOrDefault(e => e.Name == "Alias"); string alias = ((IEdmStringConstantExpression)aliasProp.Value).Value; var nameProp = propertyRef.Properties.FirstOrDefault(e => e.Name == "Name"); alternateKey[alias] = (IEdmPathExpression)nameProp.Value; } if (alternateKey.Any()) { declaredAlternateKeys.Add(alternateKey); } } } return(declaredAlternateKeys); } return(null); }
internal static bool TryAssertCollectionAsType(this IEdmCollectionExpression expression, IEdmTypeReference type, IEdmType context, bool matchExactly, out IEnumerable <EdmError> discoveredErrors) { if (!type.IsCollection()) { discoveredErrors = new EdmError[] { new EdmError(expression.Location(), EdmErrorCode.CollectionExpressionNotValidForNonCollectionType, Edm.Strings.EdmModel_Validator_Semantic_CollectionExpressionNotValidForNonCollectionType) }; return(false); } IEdmTypeReference collectionElementType = type.AsCollection().ElementType(); bool success = true; List <EdmError> errors = new List <EdmError>(); IEnumerable <EdmError> recursiveErrors; foreach (IEdmExpression element in expression.Elements) { success = TryAssertType(element, collectionElementType, context, matchExactly, out recursiveErrors) && success; errors.AddRange(recursiveErrors); } discoveredErrors = errors; return(success); }
/// <summary> /// Create the corresponding Authorization object. /// </summary> /// <param name="record">The input record.</param> /// <returns>The created <see cref="Authorization"/> object.</returns> private IEnumerable <Authorization> RetrieveAuthorizations(IEdmVocabularyAnnotatable target) { IEdmVocabularyAnnotation annotation = Model.GetVocabularyAnnotation(target, Term); if (annotation != null && annotation.Value != null && annotation.Value.ExpressionKind == EdmExpressionKind.Collection) { IEdmCollectionExpression collection = (IEdmCollectionExpression)annotation.Value; foreach (var item in collection.Elements) { IEdmRecordExpression record = item as IEdmRecordExpression; if (record == null || record.DeclaredType == null) { continue; } Authorization auth = Authorization.CreateAuthorization(record); if (auth != null) { yield return(auth); } } } }
public static IEnumerable <IEdmStructuralProperty> GetConcurrencyProperties(this IEdmModel model, IEdmEntitySet entitySet) { Contract.Assert(model != null); Contract.Assert(entitySet != null); IList <IEdmStructuralProperty> results = new List <IEdmStructuralProperty>(); IEdmEntityType entityType = entitySet.EntityType(); var annotations = model.FindVocabularyAnnotations <IEdmValueAnnotation>(entitySet, CoreVocabularyModel.ConcurrencyTerm); IEdmValueAnnotation 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.Path.Single(); IEdmProperty edmProperty = entityType.FindProperty(propertyName); IEdmStructuralProperty structuralProperty = edmProperty as IEdmStructuralProperty; if (structuralProperty != null) { results.Add(structuralProperty); } } } } } return(results); }
protected override void ProcessCollectionExpression(IEdmCollectionExpression expression) { this.BeginElement(expression, this.schemaWriter.WriteCollectionExpressionElementHeader); this.VisitExpressions(expression.Elements); this.EndElement(expression, this.schemaWriter.WriteCollectionExpressionElementEnd); }
internal void WriteCollectionExpressionElementHeader(IEdmCollectionExpression expression) { this.xmlWriter.WriteStartElement(CsdlConstants.Element_Collection); }
internal override void WriteCollectionExpressionElementEnd(IEdmCollectionExpression expression) { this.WriteEndElement(); }
private IEdmValue Eval(IEdmExpression expression, IEdmStructuredValue context) { switch (expression.ExpressionKind) { case EdmExpressionKind.IntegerConstant: return((IEdmIntegerConstantExpression)expression); case EdmExpressionKind.StringConstant: return((IEdmStringConstantExpression)expression); case EdmExpressionKind.BinaryConstant: return((IEdmBinaryConstantExpression)expression); case EdmExpressionKind.BooleanConstant: return((IEdmBooleanConstantExpression)expression); case EdmExpressionKind.DateTimeOffsetConstant: return((IEdmDateTimeOffsetConstantExpression)expression); case EdmExpressionKind.DecimalConstant: return((IEdmDecimalConstantExpression)expression); case EdmExpressionKind.FloatingConstant: return((IEdmFloatingConstantExpression)expression); case EdmExpressionKind.GuidConstant: return((IEdmGuidConstantExpression)expression); case EdmExpressionKind.DurationConstant: return((IEdmDurationConstantExpression)expression); case EdmExpressionKind.DateConstant: return((IEdmDateConstantExpression)expression); case EdmExpressionKind.TimeOfDayConstant: return((IEdmTimeOfDayConstantExpression)expression); case EdmExpressionKind.Null: return((IEdmNullExpression)expression); case EdmExpressionKind.Path: { if (context == null) { throw new InvalidOperationException(Strings.Edm_Evaluator_NoContextPath); } IEdmPathExpression pathExpression = (IEdmPathExpression)expression; IEdmValue result = context; #if NET35 // [EdmLib] Need to handle paths that bind to things other than properties. foreach (string hop in pathExpression.PathSegments) { result = FindProperty(hop, result); if (result == null) { throw new InvalidOperationException(Strings.Edm_Evaluator_UnboundPath(hop)); } } #else // Only Support Annotation in EntityType or ComplexType or Property or NavigationProperty. // Empty Path is not supported. foreach (string hop in pathExpression.PathSegments) { if (hop.Contains("@")) { var currentPathSegementInfos = hop.Split('@'); var propertyName = currentPathSegementInfos[0]; var termInfo = currentPathSegementInfos[1]; IEdmExpression termCastExpression = null; if (!Utils.StringIsNullOrWhitespace(termInfo)) { var termInfos = termInfo.Split('#'); if (termInfos.Length <= 2) { string termName = termInfos[0]; string qualifier = termInfos.Length == 2 ? termInfos[1] : null; if (Utils.StringIsNullOrWhitespace(propertyName) && this.getAnnotationExpressionForType != null) { termCastExpression = this.getAnnotationExpressionForType(this.edmModel, context.Type.Definition, termName, qualifier); } else if (!Utils.StringIsNullOrWhitespace(propertyName) && this.getAnnotationExpressionForProperty != null) { termCastExpression = this.getAnnotationExpressionForProperty(this.edmModel, context.Type.Definition, propertyName, termName, qualifier); } } } if (termCastExpression == null) { result = null; break; } result = this.Eval(termCastExpression, context); } else if (hop == "$count") { var edmCollectionValue = result as IEdmCollectionValue; if (edmCollectionValue != null) { result = new EdmIntegerConstant(edmCollectionValue.Elements.Count()); } else { result = null; break; } } else if (hop.Contains(".")) { if (this.edmModel == null) { throw new InvalidOperationException(Strings.Edm_Evaluator_TypeCastNeedsEdmModel); } IEdmType typeSegmentClientType = this.resolveTypeFromName(hop, this.edmModel); if (typeSegmentClientType == null) { result = null; break; } IEdmTypeReference operandType = result.Type; EdmValueKind operandKind = result.ValueKind; if (operandKind == EdmValueKind.Collection) { List <IEdmDelayedValue> elementValues = new List <IEdmDelayedValue>(); var collection = result as IEdmCollectionValue; foreach (IEdmDelayedValue element in collection.Elements) { if (element.Value.Type.Definition.IsOrInheritsFrom(typeSegmentClientType)) { elementValues.Add(element); } } result = new EdmCollectionValue( new EdmCollectionTypeReference(new EdmCollectionType(typeSegmentClientType.GetTypeReference(false))), elementValues); } else if (operandKind != EdmValueKind.Structured || (operandKind == EdmValueKind.Structured && !operandType.Definition.IsOrInheritsFrom(typeSegmentClientType))) { result = null; break; } } else { result = FindProperty(hop, result); if (result == null) { throw new InvalidOperationException(Strings.Edm_Evaluator_UnboundPath(hop)); } } } #endif return(result); } case EdmExpressionKind.PropertyPath: case EdmExpressionKind.NavigationPropertyPath: { EdmUtil.CheckArgumentNull(context, "context"); IEdmPathExpression pathExpression = (IEdmPathExpression)expression; IEdmValue result = context; // [EdmLib] Need to handle paths that bind to things other than properties. foreach (string hop in pathExpression.PathSegments) { result = FindProperty(hop, result); if (result == null) { throw new InvalidOperationException(Strings.Edm_Evaluator_UnboundPath(hop)); } } return(result); } case EdmExpressionKind.FunctionApplication: { IEdmApplyExpression apply = (IEdmApplyExpression)expression; IEdmFunction target = apply.AppliedFunction; if (target != null) { IList <IEdmExpression> argumentExpressions = apply.Arguments.ToList(); IEdmValue[] arguments = new IEdmValue[argumentExpressions.Count()]; { int argumentIndex = 0; foreach (IEdmExpression argument in argumentExpressions) { arguments[argumentIndex++] = this.Eval(argument, context); } } //// Static validation will have checked that the number and types of arguments are correct, //// so those checks are not performed dynamically. Func <IEdmValue[], IEdmValue> operationEvaluator; if (this.builtInFunctions.TryGetValue(target, out operationEvaluator)) { return(operationEvaluator(arguments)); } if (this.lastChanceOperationApplier != null) { return(this.lastChanceOperationApplier(target.FullName(), arguments)); } } throw new InvalidOperationException(Strings.Edm_Evaluator_UnboundFunction(target != null ? target.ToTraceString() : string.Empty)); } case EdmExpressionKind.If: { IEdmIfExpression ifExpression = (IEdmIfExpression)expression; if (((IEdmBooleanValue)this.Eval(ifExpression.TestExpression, context)).Value) { return(this.Eval(ifExpression.TrueExpression, context)); } return(this.Eval(ifExpression.FalseExpression, context)); } case EdmExpressionKind.IsType: { IEdmIsTypeExpression isType = (IEdmIsTypeExpression)expression; IEdmValue operand = this.Eval(isType.Operand, context); IEdmTypeReference targetType = isType.Type; return(new EdmBooleanConstant(MatchesType(targetType, operand))); } case EdmExpressionKind.Cast: { IEdmCastExpression castType = (IEdmCastExpression)expression; IEdmValue operand = this.Eval(castType.Operand, context); IEdmTypeReference targetType = castType.Type; return(Cast(targetType, operand)); } case EdmExpressionKind.Record: { IEdmRecordExpression record = (IEdmRecordExpression)expression; DelayedExpressionContext recordContext = new DelayedExpressionContext(this, context); List <IEdmPropertyValue> propertyValues = new List <IEdmPropertyValue>(); //// Static validation will have checked that the set of supplied properties are appropriate //// for the supplied type and have no duplicates, so those checks are not performed dynamically. foreach (IEdmPropertyConstructor propertyConstructor in record.Properties) { propertyValues.Add(new DelayedRecordProperty(recordContext, propertyConstructor)); } EdmStructuredValue result = new EdmStructuredValue(record.DeclaredType != null ? record.DeclaredType.AsStructured() : null, propertyValues); return(result); } case EdmExpressionKind.Collection: { IEdmCollectionExpression collection = (IEdmCollectionExpression)expression; DelayedExpressionContext collectionContext = new DelayedExpressionContext(this, context); List <IEdmDelayedValue> elementValues = new List <IEdmDelayedValue>(); //// Static validation will have checked that the result types of the element expressions are //// appropriate and so these checks are not performed dynamically. foreach (IEdmExpression element in collection.Elements) { elementValues.Add(this.MapLabeledExpressionToDelayedValue(element, collectionContext, context)); } EdmCollectionValue result = new EdmCollectionValue(collection.DeclaredType != null ? collection.DeclaredType.AsCollection() : null, elementValues); return(result); } case EdmExpressionKind.LabeledExpressionReference: { return(this.MapLabeledExpressionToDelayedValue(((IEdmLabeledExpressionReferenceExpression)expression).ReferencedLabeledExpression, null, context).Value); } case EdmExpressionKind.Labeled: return(this.MapLabeledExpressionToDelayedValue(expression, new DelayedExpressionContext(this, context), context).Value); case EdmExpressionKind.EnumMember: IEdmEnumMemberExpression enumMemberExpression = (IEdmEnumMemberExpression)expression; var enumMembers = enumMemberExpression.EnumMembers.ToList(); IEdmEnumType enumType = enumMembers.First().DeclaringType; IEdmEnumTypeReference enumTypeReference = new EdmEnumTypeReference(enumType, false); if (enumMembers.Count() == 1) { return(new EdmEnumValue(enumTypeReference, enumMemberExpression.EnumMembers.Single())); } else { if (!enumType.IsFlags || !EdmEnumValueParser.IsEnumIntegerType(enumType)) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Type {0} cannot be assigned with multi-values.", enumType.FullName())); } long result = 0; foreach (var enumMember in enumMembers) { long value = enumMember.Value.Value; result |= value; } return(new EdmEnumValue(enumTypeReference, new EdmEnumMemberValue(result))); } default: throw new InvalidOperationException(Strings.Edm_Evaluator_UnrecognizedExpressionKind(((int)expression.ExpressionKind).ToString(System.Globalization.CultureInfo.InvariantCulture))); } }
private IEdmValue Eval(IEdmExpression expression, IEdmStructuredValue context) { switch (expression.ExpressionKind) { case EdmExpressionKind.IntegerConstant: return((IEdmIntegerConstantExpression)expression); case EdmExpressionKind.StringConstant: return((IEdmStringConstantExpression)expression); case EdmExpressionKind.BinaryConstant: return((IEdmBinaryConstantExpression)expression); case EdmExpressionKind.BooleanConstant: return((IEdmBooleanConstantExpression)expression); case EdmExpressionKind.DateTimeConstant: return((IEdmDateTimeConstantExpression)expression); case EdmExpressionKind.DateTimeOffsetConstant: return((IEdmDateTimeOffsetConstantExpression)expression); case EdmExpressionKind.DecimalConstant: return((IEdmDecimalConstantExpression)expression); case EdmExpressionKind.FloatingConstant: return((IEdmFloatingConstantExpression)expression); case EdmExpressionKind.GuidConstant: return((IEdmGuidConstantExpression)expression); case EdmExpressionKind.TimeConstant: return((IEdmTimeConstantExpression)expression); case EdmExpressionKind.Null: return((IEdmNullExpression)expression); case EdmExpressionKind.Path: { EdmUtil.CheckArgumentNull(context, "context"); IEdmPathExpression pathExpression = (IEdmPathExpression)expression; IEdmValue result = context; foreach (string hop in pathExpression.Path) { result = this.FindProperty(hop, result); if (result == null) { throw new InvalidOperationException(Edm.Strings.Edm_Evaluator_UnboundPath(hop)); } } return(result); } case EdmExpressionKind.FunctionApplication: { IEdmApplyExpression apply = (IEdmApplyExpression)expression; IEdmExpression targetReference = apply.AppliedFunction; IEdmFunctionReferenceExpression targetFunctionReference = targetReference as IEdmFunctionReferenceExpression; if (targetFunctionReference != null) { IList <IEdmExpression> argumentExpressions = apply.Arguments.ToList(); IEdmValue[] arguments = new IEdmValue[argumentExpressions.Count()]; { int argumentIndex = 0; foreach (IEdmExpression argument in argumentExpressions) { arguments[argumentIndex++] = this.Eval(argument, context); } } IEdmFunction target = targetFunctionReference.ReferencedFunction; if (!target.IsBad()) { //// Static validation will have checked that the number and types of arguments are correct, //// so those checks are not performed dynamically. Func <IEdmValue[], IEdmValue> functionEvaluator; if (this.builtInFunctions.TryGetValue(target, out functionEvaluator)) { return(functionEvaluator(arguments)); } } if (this.lastChanceFunctionApplier != null) { return(this.lastChanceFunctionApplier(target.FullName(), arguments)); } } throw new InvalidOperationException(Edm.Strings.Edm_Evaluator_UnboundFunction(targetFunctionReference != null ? targetFunctionReference.ReferencedFunction.ToTraceString() : string.Empty)); } case EdmExpressionKind.If: { IEdmIfExpression ifExpression = (IEdmIfExpression)expression; if (((IEdmBooleanValue)this.Eval(ifExpression.TestExpression, context)).Value) { return(this.Eval(ifExpression.TrueExpression, context)); } return(this.Eval(ifExpression.FalseExpression, context)); } case EdmExpressionKind.IsType: { IEdmIsTypeExpression isType = (IEdmIsTypeExpression)expression; IEdmValue operand = this.Eval(isType.Operand, context); IEdmTypeReference targetType = isType.Type; return(new EdmBooleanConstant(MatchesType(targetType, operand))); } case EdmExpressionKind.AssertType: { IEdmAssertTypeExpression assertType = (IEdmAssertTypeExpression)expression; IEdmValue operand = this.Eval(assertType.Operand, context); IEdmTypeReference targetType = assertType.Type; return(AssertType(targetType, operand)); } case EdmExpressionKind.Record: { IEdmRecordExpression record = (IEdmRecordExpression)expression; DelayedExpressionContext recordContext = new DelayedExpressionContext(this, context); List <IEdmPropertyValue> propertyValues = new List <IEdmPropertyValue>(); //// Static validation will have checked that the set of supplied properties are appropriate //// for the supplied type and have no duplicates, so those checks are not performed dynamically. foreach (IEdmPropertyConstructor propertyConstructor in record.Properties) { propertyValues.Add(new DelayedRecordProperty(recordContext, propertyConstructor)); } EdmStructuredValue result = new EdmStructuredValue(record.DeclaredType != null ? record.DeclaredType.AsStructured() : null, propertyValues); return(result); } case EdmExpressionKind.Collection: { IEdmCollectionExpression collection = (IEdmCollectionExpression)expression; DelayedExpressionContext collectionContext = new DelayedExpressionContext(this, context); List <IEdmDelayedValue> elementValues = new List <IEdmDelayedValue>(); //// Static validation will have checked that the result types of the element expressions are //// appropriate and so these checks are not performed dynamically. foreach (IEdmExpression element in collection.Elements) { elementValues.Add(this.MapLabeledExpressionToDelayedValue(element, collectionContext, context)); } EdmCollectionValue result = new EdmCollectionValue(collection.DeclaredType != null ? collection.DeclaredType.AsCollection() : null, elementValues); return(result); } case EdmExpressionKind.LabeledExpressionReference: { return(this.MapLabeledExpressionToDelayedValue(((IEdmLabeledExpressionReferenceExpression)expression).ReferencedLabeledExpression, null, context).Value); } case EdmExpressionKind.Labeled: return(this.MapLabeledExpressionToDelayedValue(expression, new DelayedExpressionContext(this, context), context).Value); case EdmExpressionKind.ParameterReference: case EdmExpressionKind.FunctionReference: case EdmExpressionKind.PropertyReference: case EdmExpressionKind.ValueTermReference: case EdmExpressionKind.EntitySetReference: case EdmExpressionKind.EnumMemberReference: throw new InvalidOperationException("Not yet implemented: evaluation of " + expression.ExpressionKind.ToString() + " expressions."); default: throw new InvalidOperationException(Edm.Strings.Edm_Evaluator_UnrecognizedExpressionKind(((int)expression.ExpressionKind).ToString(System.Globalization.CultureInfo.InvariantCulture))); } }
public async Task ModelBuilderTest() { string expectMetadata = "<EntitySet Name=\"ETagsCustomers\" EntityType=\"Microsoft.Test.E2E.AspNet.OData.ETags.ETagsCustomer\">\r\n" + " <NavigationPropertyBinding Path=\"RelatedCustomer\" Target=\"ETagsCustomers\" />\r\n" + " <Annotation Term=\"Org.OData.Core.V1.OptimisticConcurrency\">\r\n" + " <Collection>\r\n" + " <PropertyPath>Id</PropertyPath>\r\n" + " <PropertyPath>Name</PropertyPath>\r\n" + " <PropertyPath>BoolProperty</PropertyPath>\r\n" + " <PropertyPath>ByteProperty</PropertyPath>\r\n" + " <PropertyPath>CharProperty</PropertyPath>\r\n" + " <PropertyPath>DecimalProperty</PropertyPath>\r\n" + " <PropertyPath>DoubleProperty</PropertyPath>\r\n" + " <PropertyPath>ShortProperty</PropertyPath>\r\n" + " <PropertyPath>LongProperty</PropertyPath>\r\n" + " <PropertyPath>SbyteProperty</PropertyPath>\r\n" + " <PropertyPath>FloatProperty</PropertyPath>\r\n" + " <PropertyPath>UshortProperty</PropertyPath>\r\n" + " <PropertyPath>UintProperty</PropertyPath>\r\n" + " <PropertyPath>UlongProperty</PropertyPath>\r\n" + " <PropertyPath>GuidProperty</PropertyPath>\r\n" + " <PropertyPath>DateTimeOffsetProperty</PropertyPath>\r\n" + " <PropertyPath>StringWithConcurrencyCheckAttributeProperty</PropertyPath>\r\n" + " </Collection>\r\n" + " </Annotation>\r\n" + " </EntitySet>"; // Remove indentation expectMetadata = Regex.Replace(expectMetadata, @"\r\n\s*<", @"<"); string requestUri = string.Format("{0}/odata/$metadata", this.BaseAddress); HttpResponseMessage response = await this.Client.GetAsync(requestUri); var content = await response.Content.ReadAsStringAsync(); Assert.Contains(expectMetadata, content); var stream = await response.Content.ReadAsStreamAsync(); IODataResponseMessage message = new ODataMessageWrapper(stream, response.Content.Headers); var reader = new ODataMessageReader(message); var edmModel = reader.ReadMetadataDocument(); Assert.NotNull(edmModel); var etagCustomers = edmModel.FindDeclaredEntitySet("ETagsCustomers"); Assert.NotNull(etagCustomers); var annotations = edmModel.FindDeclaredVocabularyAnnotations(etagCustomers); IEdmVocabularyAnnotation annotation = Assert.Single(annotations); Assert.NotNull(annotation); Assert.Same(CoreVocabularyModel.ConcurrencyTerm, annotation.Term); Assert.Same(etagCustomers, annotation.Target); IEdmVocabularyAnnotation valueAnnotation = annotation as IEdmVocabularyAnnotation; Assert.NotNull(valueAnnotation); Assert.NotNull(valueAnnotation.Value); IEdmCollectionExpression collection = valueAnnotation.Value as IEdmCollectionExpression; Assert.NotNull(collection); Assert.Equal(new[] { "Id", "Name", "BoolProperty", "ByteProperty", "CharProperty", "DecimalProperty", "DoubleProperty", "ShortProperty", "LongProperty", "SbyteProperty", "FloatProperty", "UshortProperty", "UintProperty", "UlongProperty", "GuidProperty", "DateTimeOffsetProperty", "StringWithConcurrencyCheckAttributeProperty" }, collection.Elements.Select(e => ((IEdmPathExpression)e).PathSegments.Single())); }
private XObject GenerateCollectionExpression(XNamespace ns, IEdmCollectionExpression collection) { var collectionElements = new XElement(ns.GetName("Collection")); foreach (var element in collection.Elements) { var elementValue = GenerateValueExpression(ns, element); if (elementValue is XAttribute) { var collectionElement = new XElement(ns.GetName(((XAttribute)elementValue).Name.ToString())); collectionElement.Add(((XAttribute)elementValue).Value); collectionElements.Add(collectionElement); } else { collectionElements.Add(elementValue); } } return collectionElements; }
protected virtual void ProcessCollectionExpression(IEdmCollectionExpression expression) { this.ProcessExpression(expression); this.VisitExpressions(expression.Elements); }
/// <summary> /// Determines if the type of an expression is compatible with the provided type /// </summary> /// <param name="expression">The expression to assert the type of.</param> /// <param name="type">The type to assert the expression as.</param> /// <param name="context">The context paths are to be evaluated in.</param> /// <param name="matchExactly">A value indicating whether the expression must match the asserted type exactly, or simply be compatible.</param> /// <param name="discoveredErrors">Errors produced if the expression does not match the specified type.</param> /// <returns>A value indicating whether the expression is valid for the given type or not.</returns> /// <remarks>If the expression has an associated type, this function will check that it matches the expected type and stop looking further. /// If an expression claims a type, it must be validated that the type is valid for the expression. If the expression does not claim a type /// this method will attempt to check the validity of the expression itself with the asserted type.</remarks> public static bool TryAssertType(this IEdmExpression expression, IEdmTypeReference type, IEdmType context, bool matchExactly, out IEnumerable <EdmError> discoveredErrors) { EdmUtil.CheckArgumentNull(expression, "expression"); // If we don't have a type to assert this passes vacuously. if (type == null || type.TypeKind() == EdmTypeKind.None) { discoveredErrors = Enumerable.Empty <EdmError>(); return(true); } switch (expression.ExpressionKind) { case EdmExpressionKind.IntegerConstant: case EdmExpressionKind.StringConstant: case EdmExpressionKind.BinaryConstant: case EdmExpressionKind.BooleanConstant: case EdmExpressionKind.DateTimeConstant: case EdmExpressionKind.DateTimeOffsetConstant: case EdmExpressionKind.DecimalConstant: case EdmExpressionKind.FloatingConstant: case EdmExpressionKind.GuidConstant: case EdmExpressionKind.TimeConstant: IEdmPrimitiveValue primitiveValue = (IEdmPrimitiveValue)expression; if (primitiveValue.Type != null) { return(TestTypeReferenceMatch(primitiveValue.Type, type, expression.Location(), matchExactly, out discoveredErrors)); } return(TryAssertPrimitiveAsType(primitiveValue, type, out discoveredErrors)); case EdmExpressionKind.Null: return(TryAssertNullAsType((IEdmNullExpression)expression, type, out discoveredErrors)); case EdmExpressionKind.Path: return(TryAssertPathAsType((IEdmPathExpression)expression, type, context, matchExactly, out discoveredErrors)); case EdmExpressionKind.FunctionApplication: IEdmApplyExpression applyExpression = (IEdmApplyExpression)expression; if (applyExpression.AppliedFunction != null) { IEdmFunctionBase function = applyExpression.AppliedFunction as IEdmFunctionBase; if (function != null) { return(TestTypeReferenceMatch(function.ReturnType, type, expression.Location(), matchExactly, out discoveredErrors)); } } // If we don't have the applied function we just assume that it will work. discoveredErrors = Enumerable.Empty <EdmError>(); return(true); case EdmExpressionKind.If: return(TryAssertIfAsType((IEdmIfExpression)expression, type, context, matchExactly, out discoveredErrors)); case EdmExpressionKind.IsType: return(TestTypeReferenceMatch(EdmCoreModel.Instance.GetBoolean(false), type, expression.Location(), matchExactly, out discoveredErrors)); case EdmExpressionKind.Record: IEdmRecordExpression recordExpression = (IEdmRecordExpression)expression; if (recordExpression.DeclaredType != null) { return(TestTypeReferenceMatch(recordExpression.DeclaredType, type, expression.Location(), matchExactly, out discoveredErrors)); } return(TryAssertRecordAsType(recordExpression, type, context, matchExactly, out discoveredErrors)); case EdmExpressionKind.Collection: IEdmCollectionExpression collectionExpression = (IEdmCollectionExpression)expression; if (collectionExpression.DeclaredType != null) { return(TestTypeReferenceMatch(collectionExpression.DeclaredType, type, expression.Location(), matchExactly, out discoveredErrors)); } return(TryAssertCollectionAsType(collectionExpression, type, context, matchExactly, out discoveredErrors)); case EdmExpressionKind.Labeled: return(TryAssertType(((IEdmLabeledExpression)expression).Expression, type, context, matchExactly, out discoveredErrors)); case EdmExpressionKind.AssertType: return(TestTypeReferenceMatch(((IEdmAssertTypeExpression)expression).Type, type, expression.Location(), matchExactly, out discoveredErrors)); case EdmExpressionKind.LabeledExpressionReference: return(TryAssertType(((IEdmLabeledExpressionReferenceExpression)expression).ReferencedLabeledExpression, type, out discoveredErrors)); default: discoveredErrors = new EdmError[] { new EdmError(expression.Location(), EdmErrorCode.ExpressionNotValidForTheAssertedType, Edm.Strings.EdmModel_Validator_Semantic_ExpressionNotValidForTheAssertedType) }; return(false); } }