private Schema CreateResourceChildSchema(ResourceChildItem resourceChildItem, OpenApiMetadataResource openApiMetadataResource)
        {
            var properties = resourceChildItem.Properties
                             .Select(
                p => new
            {
                IsRequired = p.IsIdentifying || !p.PropertyType.IsNullable,
                Key        = UniqueIdSpecification.GetUniqueIdPropertyName(p.JsonPropertyName).ToCamelCase(),
                Schema     = OpenApiMetadataDocumentHelper.CreatePropertySchema(p)
            }).Concat(
                resourceChildItem.References.Select(
                    r => new
            {
                r.IsRequired,
                Key    = r.PropertyName.ToCamelCase(),
                Schema = new Schema
                {
                    @ref = OpenApiMetadataDocumentHelper.GetDefinitionReference(
                        _openApiMetadataDefinitionsFactoryNamingStrategy.GetReferenceName(openApiMetadataResource.Resource, r))
                }
            })).Concat(
                resourceChildItem.Collections.Select(
                    c => new
            {
                IsRequired = c.Association.IsRequiredCollection,
                Key        = c.JsonPropertyName,
                Schema     = CreateCollectionSchema(c, openApiMetadataResource)
            })).Concat(
                resourceChildItem.EmbeddedObjects.Select(
                    e => new
            {
                IsRequired = false,
                Key        = e.JsonPropertyName,
                Schema     = CreateEmbeddedObjectSchema(e, openApiMetadataResource)
            })).ToList();

            var bridgeSchema = GetEdFiExtensionBridgeReferenceSchema(resourceChildItem, openApiMetadataResource);

            if (bridgeSchema != null)
            {
                properties.Add(
                    new
                {
                    IsRequired = false,
                    Key        = ExtensionCollectionKey,
                    Schema     = bridgeSchema
                });
            }

            var requiredProperties = properties.Where(x => x.IsRequired).Select(x => x.Key).ToList();

            return(new Schema
            {
                type = "object",
                required = requiredProperties.Any()
                    ? requiredProperties
                    : null,
                properties = properties.ToDictionary(k => k.Key, v => v.Schema)
            });
        }
        private Schema CreateResourceSchema(OpenApiMetadataResource openApiMetadataResource)
        {
            var resource = openApiMetadataResource.Resource;

            var properties = resource.UnifiedKeyAllProperties()
                             .Select(
                x => new PropertySchemaInfo
            {
                PropertyName = x.JsonPropertyName,
                IsRequired   = !x.PropertyType.IsNullable && !x.IsServerAssigned,
                Sort         = SortOrder(x.PropertyName, x.IsIdentifying),
                Schema       = OpenApiMetadataDocumentHelper.CreatePropertySchema(x)
            }).Concat(
                resource.Collections.Select(
                    x => new PropertySchemaInfo
            {
                PropertyName = CreateCollectionKey(x),
                IsRequired   = x.Association.IsRequiredCollection,
                Sort         = SortOrder(x.PropertyName, x.Association.IsRequiredCollection),
                Schema       = CreateCollectionSchema(x, openApiMetadataResource)
            })).Concat(
                resource.EmbeddedObjects.Select(
                    x => new PropertySchemaInfo
            {
                PropertyName = x.JsonPropertyName,
                Sort         = SortOrder(x.PropertyName, false),
                Schema       = CreateEmbeddedObjectSchema(x, openApiMetadataResource)
            })).Concat(
                resource.References.Select(
                    x => new PropertySchemaInfo
            {
                PropertyName = x.PropertyName,
                IsRequired   = x.IsRequired,
                IsReference  = true,
                Sort         = 3,
                Schema       = new Schema
                {
                    @ref = OpenApiMetadataDocumentHelper.GetDefinitionReference(
                        _openApiMetadataDefinitionsFactoryNamingStrategy.GetReferenceName(openApiMetadataResource.Resource, x))
                }

                // NOTE: currently there is an open issue with openApiMetadata-ui to address
                // objects showing up in the ui that have a reference and
                // other properties within the schema. The standard at this time does
                // not support this use case. (The error we get is:
                // Sibling values are not allowed along side $refs.
                // As of openApiMetadata-ui 3.11.0 this has not been resolved.
                // https://github.com/OAI/OpenAPI-Specification/issues/556
                // TODO: JSM - Once the standard is updated to accept sibling values along
                // side with $refs, uncomment the line below
                // isIdentity = x.Association.IsIdentifying ? true : (bool?) null
            })).Distinct(new PropertySchemaInfoComparer()).ToList();

            var propertyDict = properties.OrderBy(x => x.Sort).ThenBy(x => x.PropertyName)
                               .ToDictionary(x => x.PropertyName.ToCamelCase(), x => x.Schema);

            propertyDict.Add("_etag", EtagSchema);
            var bridgeSchema = GetEdFiExtensionBridgeReferenceSchema(resource, openApiMetadataResource);

            if (bridgeSchema != null)
            {
                propertyDict.Add(ExtensionCollectionKey, bridgeSchema);
            }

            var requiredProperties = properties
                                     .Where(x => x.IsRequired && !x.PropertyName.EqualsIgnoreCase("id"))
                                     .Select(x => x.PropertyName.ToCamelCase()).ToList();

            return(new Schema
            {
                type = "object",
                required = requiredProperties.Any()
                    ? requiredProperties
                    : null,
                properties = propertyDict
            });
        }