Exemplo n.º 1
0
        /// <summary>
        /// This method takes in a property and looks through to see if the given testProperty could be contained in it through its contained navigation properties or
        /// its nested contained navigation properties.
        /// </summary>
        /// <param name="odcmRootProperty">The property to start the search from</param>
        /// <param name="testProperty">The property to find in the from the root type</param>
        /// <param name="navigatedTypes">The types already navigated to prevent circular references</param>
        /// <param name="route">The route followed to get here</param>
        /// <returns></returns>
        private static bool IsPropertyTypeChainedContainedNavigationProperty(this OdcmProperty odcmRootProperty, OdcmProperty testProperty, HashSet <string> navigatedTypes, string route)
        {
            // check if the property already matches the type.
            if (odcmRootProperty.Type.FullName.Equals(testProperty.Type.FullName, StringComparison.OrdinalIgnoreCase))
            {
                logger.Info("Property \"{0}\" matches self contained navigation property \"{1}\" of type \"{2}\"", testProperty.Name, odcmRootProperty.Name, odcmRootProperty.Type.FullName);
                logger.Info("Possible route from service class is: {0}{1}{1}", route, Environment.NewLine);
                return(true);
            }

            // check if the base class is referenced instead.
            if (odcmRootProperty.AsOdcmClass()?.IsAncestorOfType(testProperty.AsOdcmClass() ?? null) ?? false)
            {
                logger.Info("Property \"{0}\" of type \"{1}\" matches self contained navigation property \"{2}\" of Base type \"{3}\"", testProperty.Name, testProperty.Type.FullName, odcmRootProperty.Name, odcmRootProperty.Type.FullName);
                logger.Info("Possible route from service class is: {0}{1}{1}", route, Environment.NewLine);
                return(true);
            }

            // its not this type so lets add it to the exclusion list
            navigatedTypes.Add(odcmRootProperty.Type.FullName);

            // The current type does not match. So, we get the list of contained nav properties from the given type and recursively subject it to the same test
            var matchingProperty = odcmRootProperty.Type.AsOdcmClass()?
                                   .Properties
                                   .Where(prop => prop.ContainsTarget)                          // the nave properties with containsTarget
                                   .Where(prop => !navigatedTypes.Contains(prop.Type.FullName)) // prevent any cycle business
                                   .FirstOrDefault(prop => prop.IsPropertyTypeChainedContainedNavigationProperty(testProperty, navigatedTypes, prop.IsCollection ? $"{route}/{prop.Name}/{{id}}" : $"{route}/{prop.Name}")
                                                   );

            return(matchingProperty != null);
        }