private EdmStructuralProperty?BuildStructuralProperty(Dictionary <Type, EntityTypeInfo> entityTypes,
                                                              Dictionary <Type, EdmEnumType> enumTypes, Dictionary <Type, EdmComplexType> complexTypes, PropertyInfo clrProperty)
        {
            bool isNullable           = !_metadataProvider.IsRequired(clrProperty);
            IEdmTypeReference?typeRef = PrimitiveTypeHelper.GetPrimitiveTypeRef(clrProperty, isNullable);

            if (typeRef == null)
            {
                Type?underlyingType = null;
                if (clrProperty.PropertyType.IsEnum ||
                    (underlyingType = Nullable.GetUnderlyingType(clrProperty.PropertyType)) != null && underlyingType.IsEnum)
                {
                    Type clrPropertyType = underlyingType ?? clrProperty.PropertyType;
                    if (!enumTypes.TryGetValue(clrPropertyType, out EdmEnumType? edmEnumType))
                    {
                        edmEnumType = OeEdmModelBuilder.CreateEdmEnumType(clrPropertyType);
                        enumTypes.Add(clrPropertyType, edmEnumType);
                    }
                    typeRef = new EdmEnumTypeReference(edmEnumType, underlyingType != null);
                }
                else
                {
                    if (complexTypes.TryGetValue(clrProperty.PropertyType, out EdmComplexType? edmComplexType))
                    {
                        typeRef = new EdmComplexTypeReference(edmComplexType, clrProperty.PropertyType.IsClass);
                    }
                    else
                    {
                        FKeyInfo?fkeyInfo = FKeyInfo.Create(_metadataProvider, entityTypes, this, clrProperty);
                        if (fkeyInfo != null)
                        {
                            _navigationClrProperties.Add(fkeyInfo);
                        }
                        return(null);
                    }
                }
            }
            else
            {
                if (clrProperty.PropertyType == typeof(DateTime?) && enumTypes.ContainsKey(typeof(DateTime?)))
                {
                    var edmType = enumTypes[typeof(DateTime?)];
                    typeRef = new EdmEnumTypeReference(edmType, true);
                }
            }

            EdmStructuralProperty edmProperty = clrProperty is Infrastructure.OeShadowPropertyInfo ?
                                                new OeEdmStructuralShadowProperty(EdmType, clrProperty.Name, typeRef, clrProperty) :
                                                new EdmStructuralProperty(EdmType, clrProperty.Name, typeRef);

            EdmType.AddProperty(edmProperty);
            if (_metadataProvider.IsKey(clrProperty))
            {
                _keyProperties.Add(new KeyValuePair <PropertyInfo, EdmStructuralProperty>(clrProperty, edmProperty));
            }

            return(edmProperty);
        }