public void InitializeDatabase(Action <IDatabaseInitializer> initFunc = null)
        {
            DataBaseInitializer initializer = _databaseProvider.GetDatabaseInitializer(_connectionString);

            initFunc?.Invoke(initializer);

            IEnumerable <Type> GetTypesOrderedCorrectly(IEnumerable <Type> types)
            {
                List <Type> typesList = types.ToList();

                while (typesList.Count > 0)
                {
                    for (int i = 0; i < typesList.Count; i++)
                    {
                        TypeMappingOptions typeMappingOptions = _mappingOptionsSet.GetTypeMappingOptions(typesList[i]);
                        if (!typeMappingOptions.MemberMappingOptions.OfType <ForeignObjectMappingOptions>()
                            .Where(x => typesList.Contains(x.ForeignObjectType))
                            .Any())
                        {
                            yield return(typesList[i]);

                            typesList.RemoveAt(i);
                        }
                    }
                }
            }

            foreach (Type type in GetTypesOrderedCorrectly(_relationalObjectProvider.Keys))
            {
                TypeMappingOptions typeMappingOptions = _mappingOptionsSet.GetTypeMappingOptions(type);
                initializer.AddTable(typeMappingOptions.TableName);
                foreach (FieldMappingOptions memberMappineOptions in typeMappingOptions.MemberMappingOptions.OfType <FieldMappingOptions>().OrderBy(x => x.IsPrimaryKey))
                {
                    if (memberMappineOptions.Type == MappingType.ReferenceListMapping)
                    {
                        continue;
                    }

                    if (memberMappineOptions is ForeignObjectMappingOptions foreignObjectMappingOptions)
                    {
                        initializer.AddField(foreignObjectMappingOptions.DatabaseFieldName, foreignObjectMappingOptions.KeyType);

                        FieldMappingOptions foreignFieldMappingOptions = foreignObjectMappingOptions.ForeignMember as FieldMappingOptions;
                        TypeMappingOptions  foreignTypeMappingOptions  = _mappingOptionsSet.GetTypeMappingOptions(foreignObjectMappingOptions.ForeignObjectType);

                        IEnumerable <ReferenceListMappingOptions> referenceListMappingOptions =
                            foreignTypeMappingOptions.MemberMappingOptions.OfType <ReferenceListMappingOptions>()
                            .Where(x => x.ForeignProperty == foreignObjectMappingOptions.Member);



                        initializer.AddForeignKey(
                            foreignTypeMappingOptions.TableName,
                            foreignFieldMappingOptions.DatabaseFieldName,
                            referenceListMappingOptions.Any(x => x.DeleteCascade));
                    }
                    else
                    {
                        initializer.AddField(memberMappineOptions.DatabaseFieldName, memberMappineOptions.Member.PropertyType);
                    }

                    if (memberMappineOptions.IsPrimaryKey)
                    {
                        initializer.SetIsKeyField(memberMappineOptions.IsReadonly);
                    }
                }
            }

            initializer.Flush();
        }