private static bool HasAutoExpandProperty(this IEdmModel edmModel, IEdmStructuredType structuredType, IEdmProperty pathProperty, ISet <IEdmStructuredType> visited) { if (visited.Contains(structuredType)) { return(false); } visited.Add(structuredType); List <IEdmStructuredType> structuredTypes = new List <IEdmStructuredType>(); structuredTypes.Add(structuredType); structuredTypes.AddRange(edmModel.FindAllDerivedTypes(structuredType)); foreach (IEdmStructuredType edmStructuredType in structuredTypes) { // for top type, let's retrieve its properties and the properties from base type of top type if has. // for derived type, let's retrieve the declared properties. IEnumerable <IEdmProperty> properties = edmStructuredType == structuredType ? edmStructuredType.Properties() : edmStructuredType.DeclaredProperties; foreach (IEdmProperty property in properties) { switch (property.PropertyKind) { case EdmPropertyKind.Structural: IEdmStructuralProperty structuralProperty = (IEdmStructuralProperty)property; IEdmTypeReference typeRef = property.Type.GetElementTypeOrSelf(); if (typeRef.IsComplex() && edmModel.CanExpand(typeRef.AsComplex().ComplexDefinition(), structuralProperty)) { IEdmStructuredType subStrucutredType = typeRef.AsStructured().StructuredDefinition(); if (edmModel.HasAutoExpandProperty(subStrucutredType, structuralProperty, visited)) { return(true); } } break; case EdmPropertyKind.Navigation: IEdmNavigationProperty navigationProperty = (IEdmNavigationProperty)property; if (IsAutoExpand(navigationProperty, pathProperty, edmStructuredType, edmModel)) { return(true); // find an auto-expand navigation property path } break; } } } return(false); }
private static void GetAutoExpandPaths(this IEdmModel edmModel, IEdmStructuredType structuredType, IEdmProperty pathProperty, Stack <IEdmElement> nodes, ISet <IEdmStructuredType> visited, IList <ExpandModelPath> results, bool isSelectPresent = false, ModelBoundQuerySettings querySettings = null) { if (visited.Contains(structuredType)) { return; } visited.Add(structuredType); List <IEdmStructuredType> structuredTypes = new List <IEdmStructuredType>(); structuredTypes.Add(structuredType); structuredTypes.AddRange(edmModel.FindAllDerivedTypes(structuredType)); foreach (IEdmStructuredType edmStructuredType in structuredTypes) { IEnumerable <IEdmProperty> properties; if (edmStructuredType == structuredType) { // for base type, let's retrieve its properties and the properties from base type of base type if have. properties = edmStructuredType.Properties(); } else { // for derived type, let's retrieve the declared properties. properties = edmStructuredType.DeclaredProperties; nodes.Push(edmStructuredType); // add a type cast for derived type } foreach (IEdmProperty property in properties) { switch (property.PropertyKind) { case EdmPropertyKind.Structural: IEdmStructuralProperty structuralProperty = (IEdmStructuralProperty)property; IEdmTypeReference typeRef = property.Type.GetElementTypeOrSelf(); if (typeRef.IsComplex() && edmModel.CanExpand(typeRef.AsComplex().ComplexDefinition(), structuralProperty)) { IEdmStructuredType subStructuredType = typeRef.AsStructured().StructuredDefinition(); nodes.Push(structuralProperty); edmModel.GetAutoExpandPaths(subStructuredType, structuralProperty, nodes, visited, results, isSelectPresent, querySettings); nodes.Pop(); } break; case EdmPropertyKind.Navigation: IEdmNavigationProperty navigationProperty = (IEdmNavigationProperty)property; if (IsAutoExpand(navigationProperty, pathProperty, edmStructuredType, edmModel, isSelectPresent, querySettings)) { nodes.Push(navigationProperty); results.Add(new ExpandModelPath(nodes.Reverse())); // found an auto-expand navigation property path nodes.Pop(); } break; } } if (edmStructuredType != structuredType) { nodes.Pop(); // pop the type cast for derived type } } }