/// <inheritdoc/> public override bool Match(PathSegment other) { TypeSegment otherTypeSegment = other as TypeSegment; if (otherTypeSegment == null) { return(false); } // Compare the key segment using It's declaring type. return(ReferenceEquals(ActualType, otherTypeSegment.ActualType) && ReferenceEquals(ExpectedType, otherTypeSegment.ExpectedType)); }
/// <summary> /// Try to bind namespace-qualified type cast segment. /// </summary> internal static bool TryBindTypeCastSegment(string identifier, string parenthesisExpressions, IEdmModel model, IList <PathSegment> path, PathParserSettings settings) { if (identifier == null || identifier.IndexOf('.') < 0) { // type cast should be namespace-qualified name return(false); } PathSegment preSegment = path.LastOrDefault(); if (preSegment == null) { // type cast should not be the first segment. return(false); } IEdmSchemaType schemaType = model.ResolveType(identifier, settings.EnableCaseInsensitive); if (schemaType == null) { return(false); } IEdmType targetEdmType = schemaType as IEdmType; if (targetEdmType == null) { return(false); } IEdmType previousEdmType = preSegment.EdmType; bool isNullable = false; if (previousEdmType.TypeKind == EdmTypeKind.Collection) { previousEdmType = ((IEdmCollectionType)previousEdmType).ElementType.Definition; isNullable = ((IEdmCollectionType)previousEdmType).ElementType.IsNullable; } if (!targetEdmType.IsOrInheritsFrom(previousEdmType) && !previousEdmType.IsOrInheritsFrom(targetEdmType)) { throw new Exception($"Type cast {targetEdmType.FullTypeName()} has no relationship with previous {previousEdmType.FullTypeName()}."); } // We want the type of the type segment to be a collection if the previous segment was a collection IEdmType actualTypeOfTheTypeSegment = targetEdmType; if (preSegment.EdmType.TypeKind == EdmTypeKind.Collection) { var actualEntityTypeOfTheTypeSegment = targetEdmType as IEdmEntityType; if (actualEntityTypeOfTheTypeSegment != null) { actualTypeOfTheTypeSegment = new EdmCollectionType(new EdmEntityTypeReference(actualEntityTypeOfTheTypeSegment, isNullable)); } else { // Complex collection supports type cast too. var actualComplexTypeOfTheTypeSegment = actualTypeOfTheTypeSegment as IEdmComplexType; if (actualComplexTypeOfTheTypeSegment != null) { actualTypeOfTheTypeSegment = new EdmCollectionType(new EdmComplexTypeReference(actualComplexTypeOfTheTypeSegment, isNullable)); } else { throw new Exception($"Invalid type cast of {identifier}, it should be entity or complex."); } } } TypeSegment typeCast = new TypeSegment(actualTypeOfTheTypeSegment, preSegment.EdmType, preSegment.NavigationSource, identifier); path.Add(typeCast); TryBindKeySegment(parenthesisExpressions, path); return(true); }