Example #1
0
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        public virtual ScaffoldedModel ScaffoldModel(
            string connectionString,
            DatabaseModelFactoryOptions databaseOptions,
            ModelReverseEngineerOptions modelOptions,
            ModelCodeGenerationOptions codeOptions)
        {
            if (!string.IsNullOrWhiteSpace(codeOptions.ContextName) &&
                (!_cSharpUtilities.IsValidIdentifier(codeOptions.ContextName) ||
                 _cSharpUtilities.IsCSharpKeyword(codeOptions.ContextName)))
            {
                throw new ArgumentException(
                          DesignStrings.ContextClassNotValidCSharpIdentifier(codeOptions.ContextName));
            }

            var resolvedConnectionString = _connectionStringResolver.ResolveConnectionString(connectionString);

            if (resolvedConnectionString != connectionString)
            {
                codeOptions.SuppressConnectionStringWarning = true;
            }
            else if (!codeOptions.SuppressOnConfiguring)
            {
                _reporter.WriteWarning(DesignStrings.SensitiveInformationWarning);
            }

            if (codeOptions.ConnectionString == null)
            {
                codeOptions.ConnectionString = connectionString;
            }

            var databaseModel         = _databaseModelFactory.Create(resolvedConnectionString, databaseOptions);
            var modelConnectionString = (string?)(databaseModel[ScaffoldingAnnotationNames.ConnectionString]);

            if (!string.IsNullOrEmpty(modelConnectionString))
            {
                codeOptions.ConnectionString = modelConnectionString;
                databaseModel.RemoveAnnotation(ScaffoldingAnnotationNames.ConnectionString);
            }

            var model = _factory.Create(databaseModel, modelOptions);

            if (model == null)
            {
                throw new InvalidOperationException(
                          DesignStrings.ProviderReturnedNullModel(
                              _factory.GetType().ShortDisplayName()));
            }

            if (string.IsNullOrEmpty(codeOptions.ContextName))
            {
                var annotatedName = model.GetDatabaseName();
                codeOptions.ContextName = !string.IsNullOrEmpty(annotatedName)
                    ? _code.Identifier(annotatedName + DbContextSuffix)
                    : DefaultDbContextName;
            }

            var codeGenerator = ModelCodeGeneratorSelector.Select(codeOptions.Language);

            return(codeGenerator.GenerateModel(model, codeOptions));
        }
Example #2
0
        private ScaffoldedModel ScaffoldModel(
            string connectionString,
            DatabaseModelFactoryOptions databaseOptions,
            ModelReverseEngineerOptions modelOptions,
            ModelCodeGenerationOptions codeOptions,
            bool removeNullableBoolDefaults,
            bool excludeNavigations,
            bool dbContextOnly,
            bool entitiesOnly,
            bool useSchemaFolders)
        {
            var databaseModel = databaseModelFactory.Create(connectionString, databaseOptions);

            if (removeNullableBoolDefaults)
            {
                foreach (var column in databaseModel.Tables
                         .SelectMany(table => table.Columns
                                     .Where(column => (column.StoreType == "bit" || column.StoreType == "boolean") &&
                                            !column.IsNullable &&
                                            !string.IsNullOrEmpty(column.DefaultValueSql))))
                {
                    column.DefaultValueSql = null;
                }
            }

            if (excludeNavigations)
            {
                foreach (var table in databaseModel.Tables)
                {
                    table.ForeignKeys.Clear();
                }
            }

#if CORE50 || CORE60
            var model = factory.Create(databaseModel, modelOptions);
#else
            var model = factory.Create(databaseModel, modelOptions.UseDatabaseNames);
#endif
            if (model == null)
            {
                throw new InvalidOperationException($"No model from provider {factory.GetType().ShortDisplayName()}");
            }

            var codeGenerator = ModelCodeGeneratorSelector.Select(codeOptions.Language);

            var codeModel = codeGenerator.GenerateModel(model, codeOptions);
            if (entitiesOnly)
            {
                codeModel.ContextFile = null;
            }

            if (dbContextOnly)
            {
                codeModel.AdditionalFiles.Clear();
            }

            AppendSchemaFolders(model, codeModel, useSchemaFolders);

            return(codeModel);
        }
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        public virtual ScaffoldedModel ScaffoldModel(
            string connectionString,
            DatabaseModelFactoryOptions options,
            string rootNamespace,
            string modelNamespace,
            string contextNamespace,
            string language,
            string contextDir,
            string contextName,
            ModelReverseEngineerOptions modelOptions,
            ModelCodeGenerationOptions codeOptions)
        {
            Check.NotEmpty(connectionString, nameof(connectionString));
            Check.NotNull(options, nameof(options));
            Check.NotEmpty(modelNamespace, nameof(modelNamespace));
            Check.NotEmpty(contextNamespace, nameof(contextNamespace));
            Check.NotNull(modelOptions, nameof(modelOptions));
            Check.NotNull(codeOptions, nameof(codeOptions));

            if (!string.IsNullOrWhiteSpace(contextName) &&
                (!_cSharpUtilities.IsValidIdentifier(contextName) ||
                 _cSharpUtilities.IsCSharpKeyword(contextName)))
            {
                throw new ArgumentException(
                          DesignStrings.ContextClassNotValidCSharpIdentifier(contextName));
            }

            var resolvedConnectionString = _connectionStringResolver.ResolveConnectionString(connectionString);

            if (resolvedConnectionString != connectionString)
            {
                codeOptions.SuppressConnectionStringWarning = true;
            }

            var databaseModel = _databaseModelFactory.Create(resolvedConnectionString, options);
            var model         = _factory.Create(databaseModel, modelOptions.UseDatabaseNames);

            if (model == null)
            {
                throw new InvalidOperationException(
                          DesignStrings.ProviderReturnedNullModel(
                              _factory.GetType().ShortDisplayName()));
            }

            if (string.IsNullOrEmpty(contextName))
            {
                contextName = DefaultDbContextName;

                var annotatedName = model.GetDatabaseName();
                if (!string.IsNullOrEmpty(annotatedName))
                {
                    contextName = _code.Identifier(annotatedName + DbContextSuffix);
                }
            }

            var codeGenerator = ModelCodeGeneratorSelector.Select(language);

            return(codeGenerator.GenerateModel(model, rootNamespace, modelNamespace, contextNamespace, contextDir ?? string.Empty, contextName, connectionString, codeOptions));
        }
Example #4
0
        public virtual IModel Create([NotNull] string connectionString, [CanBeNull] TableSelectionSet tableSelectionSet)
        {
            Check.NotEmpty(connectionString, nameof(connectionString));

            var schemaInfo = _databaseModelFactory.Create(connectionString, tableSelectionSet ?? TableSelectionSet.All);

            return(CreateFromDatabaseModel(schemaInfo));
        }
Example #5
0
        private DatabaseModel GetDatabaseModel(IDatabaseModelFactory factory)
        {
            this._logger.LogInformation("Loading database model ...");

            var database         = this.Options.Database;
            var connectionString = this.ResolveConnectionString(database);

            return(factory.Create(connectionString, database.Tables, database.Schemas));
        }
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        public virtual ScaffoldedModel ScaffoldModel(
            string connectionString,
            IEnumerable <string> tables,
            IEnumerable <string> schemas,
            string @namespace,
            string language,
            string contextDir,
            string contextName,
            bool useDataAnnotations,
            bool useDatabaseNames)
        {
            Check.NotEmpty(connectionString, nameof(connectionString));
            Check.NotNull(tables, nameof(tables));
            Check.NotNull(schemas, nameof(schemas));
            Check.NotEmpty(@namespace, nameof(@namespace));
            Check.NotNull(language, nameof(language));

            if (!string.IsNullOrWhiteSpace(contextName) &&
                (!_cSharpUtilities.IsValidIdentifier(contextName) ||
                 _cSharpUtilities.IsCSharpKeyword(contextName)))
            {
                throw new ArgumentException(
                          DesignStrings.ContextClassNotValidCSharpIdentifier(contextName));
            }

            var databaseModel = _databaseModelFactory.Create(connectionString, tables, schemas);
            var model         = _factory.Create(databaseModel, useDatabaseNames);

            if (model == null)
            {
                throw new InvalidOperationException(
                          DesignStrings.ProviderReturnedNullModel(
                              _factory.GetType().ShortDisplayName()));
            }

            if (string.IsNullOrEmpty(contextName))
            {
                contextName = DefaultDbContextName;

                var annotatedName = model.Scaffolding().DatabaseName;
                if (!string.IsNullOrEmpty(annotatedName))
                {
                    contextName = _cSharpUtilities.GenerateCSharpIdentifier(
                        annotatedName + DbContextSuffix,
                        existingIdentifiers: null,
                        singularizePluralizer: null);
                }
            }

            var codeGenerator = ModelCodeGeneratorSelector.Select(language);

            return(codeGenerator.GenerateModel(model, @namespace, contextDir ?? string.Empty, contextName, connectionString, useDataAnnotations));
        }
Example #7
0
        public virtual IModel Create(string connectionString, TableSelectionSet tableSelectionSet)
        {
            Check.NotEmpty(connectionString, nameof(connectionString));

            var databaseModel = _databaseModelFactory.Create(connectionString, tableSelectionSet ?? TableSelectionSet.All);

            if (tableSelectionSet != null)
            {
                CheckSelectionsMatched(tableSelectionSet);
            }

            return(CreateFromDatabaseModel(databaseModel));
        }
Example #8
0
        public virtual IModel Create(
            string connectionString,
            IEnumerable <string> tables,
            IEnumerable <string> schemas,
            bool useDatabaseNames)
        {
            Check.NotEmpty(connectionString, nameof(connectionString));
            Check.NotNull(tables, nameof(tables));
            Check.NotNull(schemas, nameof(schemas));

            var databaseModel = _databaseModelFactory.Create(connectionString, tables, schemas);

            return(CreateFromDatabaseModel(databaseModel, useDatabaseNames));
        }
        private DatabaseModel GetDatabaseModel(IDatabaseModelFactory factory)
        {
            _logger.LogInformation("Loading database model ...");

            var database = Options.Database;

            //do not evaluate connection string resolving (cfr. { or } in password => crash)
            var shouldEvaluate = Options.Variables.ShouldEvaluate;

            Options.Variables.ShouldEvaluate = false;

            var connectionString = ResolveConnectionString(database);

            Options.Variables.ShouldEvaluate = shouldEvaluate;

            var options = new DatabaseModelFactoryOptions(database.Tables, database.Schemas);

            return(factory.Create(connectionString, options));
        }
Example #10
0
        //public ScaffoldedModel ScaffoldModel(string connectionString, IEnumerable<string> tables, IEnumerable<string> schemas, string @namespace,
        //    string language, string contextDir, string contextName, ModelReverseEngineerOptions modelOptions,
        //    ModelCodeGenerationOptions codeOptions)
        //{
        //    var fullTables = tables.Select(x => new EntityType { FileName = x, DisplayName = x, Name = x }).ToList();

        //    return ScaffoldModel(connectionString, fullTables, schemas, @namespace, language, contextDir, contextName,
        //        modelOptions, codeOptions);

        //}

        public ScaffoldedModel ScaffoldModel(string connectionString, [NoEnumeration] IEnumerable <EntityType> tables, IEnumerable <string> schemas, string @namespace,
                                             string language, string contextDir, string contextName, ModelReverseEngineerOptions modelOptions,
                                             ModelCodeGenerationOptions codeOptions)
        {
            var entityTypes = tables.ToList();
            var resolvedConnectionString = _connectionStringResolver.ResolveConnectionString(connectionString);

            if (resolvedConnectionString != connectionString)
            {
                codeOptions.SuppressConnectionStringWarning = true;
            }

            var databaseModel = _databaseModelFactory.Create(resolvedConnectionString, entityTypes.Select(x => x.Name).ToList(), schemas);

            var customDatabaseModel = CreateCustomDatabaseModel(databaseModel, entityTypes);
            var model = _scaffoldingModelFactory.Create(customDatabaseModel, modelOptions.UseDatabaseNames);

            if (model == null)
            {
                // TODO: thow some other proper exception
                throw new Exception("Model is null");
                //throw new InvalidOperationException(
                //    DesignStrings.ProviderReturnedNullModel(
                //        _factory.GetType().ShortDisplayName()));
            }

            // TODO: Handle what to do when the contextName is empty
            //if (string.IsNullOrEmpty(contextName))
            //{
            //    contextName = DefaultDbContextName;

            //    var annotatedName = model.Scaffolding().DatabaseName;
            //    if (!string.IsNullOrEmpty(annotatedName))
            //    {
            //        contextName = _cSharpHelper.Identifier(annotatedName + DbContextSuffix);
            //    }
            //}

            var codeGenerator = _modelCodeGeneratorSelector.Select(language);

            return(codeGenerator.GenerateModel(model, @namespace, contextDir ?? string.Empty, contextName, connectionString, codeOptions));
        }
Example #11
0
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        public virtual ReverseEngineerFiles Generate(
            string connectionString,
            IEnumerable <string> tables,
            IEnumerable <string> schemas,
            string projectPath,
            string outputPath,
            string rootNamespace,
            string contextName,
            bool useDataAnnotations,
            bool overwriteFiles,
            bool useDatabaseNames)
        {
            if (connectionString == null)
            {
                throw new ArgumentNullException(nameof(connectionString));
            }
            if (tables == null)
            {
                throw new ArgumentNullException(nameof(tables));
            }
            if (schemas == null)
            {
                throw new ArgumentNullException(nameof(schemas));
            }
            if (projectPath == null)
            {
                throw new ArgumentNullException(nameof(projectPath));
            }
            if (rootNamespace == null)
            {
                throw new ArgumentNullException(nameof(rootNamespace));
            }

            if (!string.IsNullOrWhiteSpace(contextName) &&
                (!_cSharpUtilities.IsValidIdentifier(contextName) ||
                 _cSharpUtilities.IsCSharpKeyword(contextName)))
            {
                throw new ArgumentException(
                          DesignStrings.ContextClassNotValidCSharpIdentifier(contextName));
            }

            var databaseModel = _databaseModelFactory.Create(connectionString, tables, schemas);
            //var model = _factory.Create(connectionString, tables, schemas, useDatabaseNames);
            var model = _factory.Create(databaseModel, useDatabaseNames);

            if (model == null)
            {
                throw new InvalidOperationException(
                          DesignStrings.ProviderReturnedNullModel(
                              _factory.GetType().ShortDisplayName()));
            }

            outputPath = string.IsNullOrWhiteSpace(outputPath) ? null : outputPath;
            var subNamespace = SubnamespaceFromOutputPath(projectPath, outputPath);

            var @namespace = rootNamespace;

            if (!string.IsNullOrEmpty(subNamespace))
            {
                @namespace += "." + subNamespace;
            }

            if (string.IsNullOrEmpty(contextName))
            {
                contextName = DefaultDbContextName;

                var annotatedName = model.Scaffolding().DatabaseName;
                if (!string.IsNullOrEmpty(annotatedName))
                {
                    contextName = _cSharpUtilities.GenerateCSharpIdentifier(
                        annotatedName + DbContextSuffix,
                        existingIdentifiers: null,
                        singularizePluralizer: null);
                }
            }

            CheckOutputFiles(outputPath ?? projectPath, contextName, model, overwriteFiles);

            return(ScaffoldingCodeGenerator.WriteCode(model, outputPath ?? projectPath, @namespace, contextName, connectionString, useDataAnnotations));
        }
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        public virtual ReverseEngineerFiles Generate(
            string connectionString,
            IEnumerable <string> tables,
            IEnumerable <string> schemas,
            string projectPath,
            string outputPath,
            string rootNamespace,
            string contextName,
            bool useDataAnnotations,
            bool overwriteFiles,
            bool useDatabaseNames)
        {
            Check.NotEmpty(connectionString, nameof(connectionString));
            Check.NotNull(tables, nameof(tables));
            Check.NotNull(schemas, nameof(schemas));
            Check.NotEmpty(projectPath, nameof(projectPath));
            Check.NotEmpty(rootNamespace, nameof(rootNamespace));

            if (!string.IsNullOrWhiteSpace(contextName) &&
                (!_cSharpUtilities.IsValidIdentifier(contextName) ||
                 _cSharpUtilities.IsCSharpKeyword(contextName)))
            {
                throw new ArgumentException(
                          DesignStrings.ContextClassNotValidCSharpIdentifier(contextName));
            }

            var databaseModel = _databaseModelFactory.Create(connectionString, tables, schemas);
            var model         = _factory.Create(databaseModel, useDatabaseNames);

            if (model == null)
            {
                throw new InvalidOperationException(
                          DesignStrings.ProviderReturnedNullModel(
                              _factory.GetType().ShortDisplayName()));
            }

            projectPath = projectPath.TrimEnd(_directorySeparatorChars);

            var fullProjectPath = Path.GetFullPath(projectPath);
            var fullOutputPath  = string.IsNullOrEmpty(outputPath)
                ? fullProjectPath
                : Path.GetFullPath(Path.Combine(projectPath, outputPath));

            var @namespace = rootNamespace;

            if (!string.Equals(fullOutputPath, fullProjectPath) &&
                fullOutputPath.StartsWith(fullProjectPath, StringComparison.Ordinal))
            {
                var relativeOutputPath = fullOutputPath.Substring(fullProjectPath.Length + 1);
                @namespace += "." + string.Join(
                    ".", relativeOutputPath
                    .Split(_directorySeparatorChars, StringSplitOptions.RemoveEmptyEntries)
                    .Select(
                        p => _cSharpUtilities.GenerateCSharpIdentifier(
                            p,
                            existingIdentifiers: null,
                            singularizePluralizer: null)));
            }

            if (string.IsNullOrEmpty(contextName))
            {
                contextName = DefaultDbContextName;

                var annotatedName = model.Scaffolding().DatabaseName;
                if (!string.IsNullOrEmpty(annotatedName))
                {
                    contextName = _cSharpUtilities.GenerateCSharpIdentifier(
                        annotatedName + DbContextSuffix,
                        existingIdentifiers: null,
                        singularizePluralizer: null);
                }
            }

            CheckOutputFiles(fullOutputPath, contextName, model, overwriteFiles);

            return(ScaffoldingCodeGenerator.WriteCode(model, fullOutputPath, @namespace, contextName, connectionString, useDataAnnotations));
        }