public override DatabaseModel Create(DbConnection connection, DatabaseModelFactoryOptions options)
        {
            Check.NotNull(connection, nameof(connection));
            Check.NotNull(options, nameof(options));

            var databaseModel = new DatabaseModel();

            var connectionStartedOpen = connection.State == ConnectionState.Open;

            if (!connectionStartedOpen)
            {
                connection.Open();
            }

            try
            {
                SetupMySqlOptions(connection);

                databaseModel.DatabaseName  = connection.Database;
                databaseModel.DefaultSchema = GetDefaultSchema(connection);

                var schemaList  = Enumerable.Empty <string>().ToList();
                var tableList   = options.Tables.ToList();
                var tableFilter = GenerateTableFilter(tableList, schemaList);

                var tables = GetTables(connection, tableFilter);
                foreach (var table in tables)
                {
                    table.Database = databaseModel;
                    databaseModel.Tables.Add(table);
                }

                return(databaseModel);
            }
            finally
            {
                if (!connectionStartedOpen)
                {
                    connection.Close();
                }
            }
        }
Esempio n. 2
0
        public void CanEnumerateTypeAlias()
        {
            // Arrange
            var factory = new SqlServerDacpacDatabaseModelFactory(null);
            var tables  = new List <string> {
                "[dbo].[TypeAlias]"
            };
            var options = new DatabaseModelFactoryOptions(tables, new List <string>());

            // Act
            var dbModel = factory.Create(dacpacQuirk, options);

            // Assert
            Assert.AreEqual(1, dbModel.Tables.Count());

            Assert.AreEqual("TypeAlias", dbModel.Tables[0].Name);
            Assert.AreEqual(2, dbModel.Tables[0].Columns.Count);

            Assert.AreEqual("nvarchar(max)", dbModel.Tables[0].Columns[1].StoreType);
        }
Esempio n. 3
0
    public override DatabaseModel Create(DbConnection connection, DatabaseModelFactoryOptions options)
    {
        var databaseModel = new DatabaseModel();

        var connectionStartedOpen = connection.State == ConnectionState.Open;

        if (!connectionStartedOpen)
        {
            connection.Open();
        }

        var serverVersion = FbServerProperties.ParseServerVersion(connection.ServerVersion);

        MajorVersionNumber = serverVersion.Major;

        try
        {
            databaseModel.DatabaseName  = connection.Database;
            databaseModel.DefaultSchema = GetDefaultSchema(connection);

            var schemaList  = new List <string>();
            var tableList   = options.Tables.ToList();
            var tableFilter = GenerateTableFilter(tableList, schemaList);

            var tables = GetTables(connection, tableFilter);
            foreach (var table in tables)
            {
                table.Database = databaseModel;
                databaseModel.Tables.Add(table);
            }

            return(databaseModel);
        }
        finally
        {
            if (!connectionStartedOpen)
            {
                connection.Close();
            }
        }
    }
        private static ScaffoldedModel ScaffoldModel(
            string connectionString,
            DatabaseModelFactoryOptions databaseOptions,
            ModelReverseEngineerOptions modelOptions,
            ModelCodeGenerationOptions codeOptions,
            bool removeNullableBoolDefaults,
            ServiceProvider serviceProvider)
        {
            var _databaseModelFactory = serviceProvider.GetService <IDatabaseModelFactory>();
            var _factory  = serviceProvider.GetService <IScaffoldingModelFactory>();
            var _selector = serviceProvider.GetService <IModelCodeGeneratorSelector>();

            var databaseModel = _databaseModelFactory.Create(connectionString, databaseOptions);

            if (removeNullableBoolDefaults)
            {
                foreach (var column in databaseModel.Tables
                         .SelectMany(table => table.Columns
                                     .Where(column => column.StoreType == "bit" &&
                                            !column.IsNullable &&
                                            !string.IsNullOrEmpty(column.DefaultValueSql))))
                {
                    column.DefaultValueSql = null;
                }
            }
#if CORE50
            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 = _selector.Select(codeOptions.Language);

            return(codeGenerator.GenerateModel(model, codeOptions));
        }
Esempio n. 5
0
        public void CanEnumerateSelectedQuirkObjects()
        {
            // Arrange
            var factory = new SqlServerDacpacDatabaseModelFactory(null);
            var tables  = new List <string> {
                "[dbo].[FilteredIndexTable]", "[dbo].[DefaultComputedValues]"
            };
            var options = new DatabaseModelFactoryOptions(tables, new List <string>());

            // Act
            var dbModel = factory.Create(dacpacQuirk, options);

            // Assert
            Assert.AreEqual(2, dbModel.Tables.Count());

            Assert.AreEqual("FilteredIndexTable", dbModel.Tables[1].Name);
            Assert.AreEqual(0, dbModel.Tables[1].ForeignKeys.Count);
            Assert.AreEqual(2, dbModel.Tables[1].Columns.Count);

            Assert.AreEqual("DefaultComputedValues", dbModel.Tables[0].Name);
            Assert.AreEqual(5, dbModel.Tables[0].Columns.Count);
        }
Esempio n. 6
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 override DatabaseModel Create(
            DbConnection connection,
            DatabaseModelFactoryOptions options)
        {
            Check.NotNull(connection, nameof(connection));
            Check.NotNull(options, nameof(options));

            var databaseModel = new DatabaseModel();

            var connectionStartedOpen = connection.State == ConnectionState.Open;

            if (!connectionStartedOpen)
            {
                connection.Open();
            }

            try
            {
                var tableList   = options.Tables.ToList();
                var tableFilter = GenerateTableFilter(tableList.Select(Parse).ToList());

                foreach (var table in GetTables(connection, tableFilter))
                {
                    table.Database = databaseModel;
                    databaseModel.Tables.Add(table);
                }

                return(databaseModel);
            }
            finally
            {
                if (!connectionStartedOpen)
                {
                    connection.Close();
                }
            }
        }
Esempio n. 7
0
 /// <summary>
 ///     Connects to the database using the given connection and creates a <see cref="DatabaseModel" />
 ///     for the database.
 /// </summary>
 /// <param name="connection">The connection to the database to reverse engineer.</param>
 /// <param name="options">The options specifying which metadata to read.</param>
 /// <returns>The database model.</returns>
 public abstract DatabaseModel Create(DbConnection connection, DatabaseModelFactoryOptions options);
Esempio n. 8
0
 /// <summary>
 ///     Connects to the database using the given connection string and creates a <see cref="DatabaseModel" />
 ///     for the database.
 /// </summary>
 /// <param name="connectionString">The connection string for the database to reverse engineer.</param>
 /// <param name="options">The options specifying which metadata to read.</param>
 /// <returns>The database model.</returns>
 public abstract DatabaseModel Create(string connectionString, DatabaseModelFactoryOptions options);
Esempio n. 9
0
        public override DatabaseModel Create(string connectionString, DatabaseModelFactoryOptions options)
        {
            var connection = new ClickHouseConnection(connectionString);

            return(Create(connection, options));
        }
Esempio n. 10
0
 public DatabaseModel Create(string connectionString, DatabaseModelFactoryOptions options) => throw new NotImplementedException();
        /// <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 override DatabaseModel Create(DbConnection connection, DatabaseModelFactoryOptions options)
        {
            Check.NotNull(connection, nameof(connection));
            Check.NotNull(options, nameof(options));

            if (options.Schemas.Any())
            {
                _logger.SchemasNotSupportedWarning();
            }

            var databaseModel = new DatabaseModel();

            var connectionStartedOpen = connection.State == ConnectionState.Open;

            if (!connectionStartedOpen)
            {
                connection.Open();

                SpatialiteLoader.TryLoad(connection);
            }

            try
            {
                databaseModel.DatabaseName = GetDatabaseName(connection);

                foreach (var table in GetTables(connection, options.Tables))
                {
                    table.Database = databaseModel;
                    databaseModel.Tables.Add(table);
                }

                foreach (var table in databaseModel.Tables)
                {
                    foreach (var foreignKey in GetForeignKeys(connection, table, databaseModel.Tables))
                    {
                        foreignKey.Table = table;
                        table.ForeignKeys.Add(foreignKey);
                    }
                }

                var nullableKeyColumns = databaseModel.Tables
                                         .Where(t => t.PrimaryKey != null).SelectMany(t => t.PrimaryKey.Columns)
                                         .Concat(databaseModel.Tables.SelectMany(t => t.ForeignKeys).SelectMany(fk => fk.PrincipalColumns))
                                         .Where(c => c.IsNullable)
                                         .Distinct();
                foreach (var column in nullableKeyColumns)
                {
                    // TODO: Consider warning
                    column.IsNullable = false;
                }
            }
            finally
            {
                if (!connectionStartedOpen)
                {
                    connection.Close();
                }
            }

            return(databaseModel);
        }
        public override DatabaseModel Create(DbConnection connection, DatabaseModelFactoryOptions options)
        {
            Check.NotNull(connection, nameof(connection));
            Check.NotNull(options, nameof(options));

            var databaseModel = new DatabaseModel();

            var connectionStartedOpen = connection.State == ConnectionState.Open;

            if (!connectionStartedOpen)
            {
                connection.Open();
            }

            try
            {
                _compatibilityLevel = GetCompatibilityLevel(connection);
                _engineEdition      = GetEngineEdition(connection);

                databaseModel.DatabaseName  = connection.Database;
                databaseModel.DefaultSchema = GetDefaultSchema(connection);
                databaseModel.Collation     = GetCollation(connection);

                var typeAliases = GetTypeAliases(connection);

                var schemaList   = options.Schemas.ToList();
                var schemaFilter = GenerateSchemaFilter(schemaList);
                var tableList    = options.Tables.ToList();
                var tableFilter  = GenerateTableFilter(tableList.Select(Parse).ToList(), schemaFilter);

                if (SupportsSequences())
                {
                    GetSequences(connection, databaseModel, schemaFilter, typeAliases);
                }

                GetTables(connection, databaseModel, tableFilter, typeAliases);

                foreach (var schema in schemaList
                         .Except(
                             databaseModel.Sequences.Select(s => s.Schema)
                             .Concat(databaseModel.Tables.Select(t => t.Schema))))
                {
                    _logger.MissingSchemaWarning(schema);
                }

                foreach (var table in tableList)
                {
                    var(parsedSchema, parsedTableName) = Parse(table);
                    if (!databaseModel.Tables.Any(
                            t => !string.IsNullOrEmpty(parsedSchema) &&
                            t.Schema == parsedSchema ||
                            t.Name == parsedTableName))
                    {
                        _logger.MissingTableWarning(table);
                    }
                }

                return(databaseModel);
            }
            finally
            {
                _compatibilityLevel = null;
                _engineEdition      = null;

                if (!connectionStartedOpen)
                {
                    connection.Close();
                }
            }
Esempio n. 13
0
        static void Main(string[] args)
        {
            var connectionString = args.Length > 0
                ? args[0]
                : throw new Exception("Pass connection string as a first parameter");

            var scaffolder = CreateMssqlScaffolder();

            var dbOpts      = new DatabaseModelFactoryOptions();
            var modelOpts   = new ModelReverseEngineerOptions();
            var codeGenOpts = new ModelCodeGenerationOptions()
            {
                RootNamespace    = "TypedDataContext",
                ContextName      = "DataContext",
                ContextNamespace = "TypedDataContext.Context",
                ModelNamespace   = "TypedDataContext.Models",
                SuppressConnectionStringWarning = true
            };

            var scaffoldedModelSources = scaffolder.ScaffoldModel(connectionString, dbOpts, modelOpts, codeGenOpts);
            var sourceFiles            = new List <string> {
                scaffoldedModelSources.ContextFile.Code
            };

            sourceFiles.AddRange(scaffoldedModelSources.AdditionalFiles.Select(f => f.Code));

            using var peStream = new MemoryStream();

            var enableLazyLoading = false;
            var result            = GenerateCode(sourceFiles, enableLazyLoading).Emit(peStream);

            if (!result.Success)
            {
                var failures = result.Diagnostics
                               .Where(diagnostic => diagnostic.IsWarningAsError ||
                                      diagnostic.Severity == DiagnosticSeverity.Error);

                var error = failures.FirstOrDefault();
                throw new Exception($"{error?.Id}: {error?.GetMessage()}");
            }

            var assemblyLoadContext = new AssemblyLoadContext("DbContext", isCollectible: !enableLazyLoading);

            peStream.Seek(0, SeekOrigin.Begin);
            var assembly = assemblyLoadContext.LoadFromStream(peStream);

            var type = assembly.GetType("TypedDataContext.Context.DataContext");

            _ = type ?? throw new Exception("DataContext type not found");

            var constr = type.GetConstructor(Type.EmptyTypes);

            _ = constr ?? throw new Exception("DataContext ctor not found");

            DbContext dynamicContext = (DbContext)constr.Invoke(null);
            var       entityTypes    = dynamicContext.Model.GetEntityTypes();

            Console.WriteLine($"Context contains {entityTypes.Count()} types");

            foreach (var entityType in dynamicContext.Model.GetEntityTypes())
            {
                var items = (IQueryable <object>)dynamicContext.Query(entityType.Name);

                Console.WriteLine($"Entity type: {entityType.Name} contains {items.Count()} items");
            }

            Console.ReadKey();

            if (!enableLazyLoading)
            {
                assemblyLoadContext.Unload();
            }
        }
Esempio n. 14
0
        private static ScaffoldedModel ScaffoldModel(
            string connectionString,
            DatabaseModelFactoryOptions databaseOptions,
            ModelReverseEngineerOptions modelOptions,
            ModelCodeGenerationOptions codeOptions,
            bool removeNullableBoolDefaults,
            bool excludeNavigations,
            bool dbContextOnly,
            bool entitiesOnly,
            bool useSchemaFolders,
            ServiceProvider serviceProvider)
        {
            var _databaseModelFactory = serviceProvider.GetService <IDatabaseModelFactory>();
            var _factory  = serviceProvider.GetService <IScaffoldingModelFactory>();
            var _selector = serviceProvider.GetService <IModelCodeGeneratorSelector>();

            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 = _selector.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);
        }
Esempio n. 15
0
        public ReverseEngineerResult GenerateFiles(ReverseEngineerCommandOptions reverseEngineerOptions)
        {
            var errors   = new List <string>();
            var warnings = new List <string>();
            var reporter = new OperationReporter(
                new OperationReportHandler(
                    m => errors.Add(m),
                    m => warnings.Add(m)));

            var serviceProvider = ServiceProviderBuilder.Build(reverseEngineerOptions);
            var scaffolder      = serviceProvider.GetService <IReverseEngineerScaffolder>();

            var schemas = new List <string>();

            if (reverseEngineerOptions.DefaultDacpacSchema != null)
            {
                schemas.Add(reverseEngineerOptions.DefaultDacpacSchema);
            }

            var outputDir = !string.IsNullOrEmpty(reverseEngineerOptions.OutputPath)
               ? Path.IsPathFullyQualified(reverseEngineerOptions.OutputPath)
                    ? reverseEngineerOptions.OutputPath
                    : Path.GetFullPath(Path.Combine(reverseEngineerOptions.ProjectPath, reverseEngineerOptions.OutputPath))
                : reverseEngineerOptions.ProjectPath;

            var outputContextDir = !string.IsNullOrEmpty(reverseEngineerOptions.OutputContextPath)
               ? Path.IsPathFullyQualified(reverseEngineerOptions.OutputContextPath)
                    ? reverseEngineerOptions.OutputContextPath
                    : Path.GetFullPath(Path.Combine(reverseEngineerOptions.ProjectPath, reverseEngineerOptions.OutputContextPath))
                : outputDir;

            var modelNamespace = !string.IsNullOrEmpty(reverseEngineerOptions.ModelNamespace)
                ? reverseEngineerOptions.ProjectRootNamespace + "." + reverseEngineerOptions.ModelNamespace
                : PathHelper.GetNamespaceFromOutputPath(outputDir, reverseEngineerOptions.ProjectPath, reverseEngineerOptions.ProjectRootNamespace);

            var contextNamespace = !string.IsNullOrEmpty(reverseEngineerOptions.ContextNamespace)
                ? reverseEngineerOptions.ProjectRootNamespace + "." + reverseEngineerOptions.ContextNamespace
                : PathHelper.GetNamespaceFromOutputPath(outputContextDir, reverseEngineerOptions.ProjectPath, reverseEngineerOptions.ProjectRootNamespace);

            var modelOptions = new ModelReverseEngineerOptions
            {
                UseDatabaseNames = reverseEngineerOptions.UseDatabaseNames,
            };

            var codeOptions = new ModelCodeGenerationOptions
            {
                UseDataAnnotations = !reverseEngineerOptions.UseFluentApiOnly,
                Language           = "C#",
                ContextName        = reverseEngineerOptions.ContextClassName,
                ContextDir         = outputContextDir,
                RootNamespace      = null,
                ContextNamespace   = contextNamespace,
                ModelNamespace     = modelNamespace,
                SuppressConnectionStringWarning = false,
                ConnectionString = reverseEngineerOptions.ConnectionString,
            };

            var dbOptions = new DatabaseModelFactoryOptions(reverseEngineerOptions.Tables.Select(m => m.Name), schemas);

            var scaffoldedModel = scaffolder.ScaffoldModel(
                reverseEngineerOptions.Dacpac ?? reverseEngineerOptions.ConnectionString,
                dbOptions,
                modelOptions,
                codeOptions);

            var filePaths = scaffolder.Save(
                scaffoldedModel,
                Path.Combine(reverseEngineerOptions.ProjectPath, reverseEngineerOptions.OutputPath ?? string.Empty),
                overwriteFiles: true);

            string fixedNamespace = modelNamespace != contextNamespace
                ? modelNamespace
                : null;

            PostProcessContext(filePaths.ContextFile, reverseEngineerOptions, fixedNamespace);

            foreach (var file in filePaths.AdditionalFiles)
            {
                PostProcess(file);
            }

            PostProcess(filePaths.ContextFile);

            var result = new ReverseEngineerResult
            {
                EntityErrors        = errors,
                EntityWarnings      = warnings,
                EntityTypeFilePaths = filePaths.AdditionalFiles,
                ContextFilePath     = filePaths.ContextFile,
            };

            return(result);
        }
Esempio n. 16
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 override DatabaseModel Create(DbConnection connection, DatabaseModelFactoryOptions options)
        {
            Check.NotNull(connection, nameof(connection));
            Check.NotNull(options, nameof(options));

            var databaseModel = new DatabaseModel();

            var connectionStartedOpen = connection.State == ConnectionState.Open;

            if (!connectionStartedOpen)
            {
                connection.Open();
            }

            try
            {
                databaseModel.DatabaseName  = connection.Database;
                databaseModel.DefaultSchema = GetDefaultSchema(connection);

                var typeAliases = GetTypeAliases(connection);

                var schemaList   = options.Schemas.ToList();
                var schemaFilter = GenerateSchemaFilter(schemaList);
                var tableList    = options.Tables.ToList();
                var tableFilter  = GenerateTableFilter(tableList.Select(Parse).ToList(), schemaFilter);

                if (Version.TryParse(connection.ServerVersion, out var serverVersion) &&
                    serverVersion.Major >= 11)
                {
                    foreach (var sequence in GetSequences(connection, schemaFilter, typeAliases))
                    {
                        sequence.Database = databaseModel;
                        databaseModel.Sequences.Add(sequence);
                    }
                }

                foreach (var table in GetTables(connection, tableFilter, typeAliases))
                {
                    table.Database = databaseModel;
                    databaseModel.Tables.Add(table);
                }

                foreach (var schema in schemaList
                         .Except(
                             databaseModel.Sequences.Select(s => s.Schema)
                             .Concat(databaseModel.Tables.Select(t => t.Schema))))
                {
                    _logger.MissingSchemaWarning(schema);
                }

                foreach (var table in tableList)
                {
                    var(parsedSchema, parsedTableName) = Parse(table);
                    if (!databaseModel.Tables.Any(
                            t => !string.IsNullOrEmpty(parsedSchema) &&
                            t.Schema == parsedSchema ||
                            t.Name == parsedTableName))
                    {
                        _logger.MissingTableWarning(table);
                    }
                }

                return(databaseModel);
            }
            finally
            {
                if (!connectionStartedOpen)
                {
                    connection.Close();
                }
            }
        }
Esempio n. 17
0
 public override DatabaseModel Create(string connectionString, DatabaseModelFactoryOptions options)
 {
     using var connection = new SpannerConnection(connectionString);
     return(Create(connection, options));
 }
        public ReverseEngineerResult GenerateFiles(ReverseEngineerCommandOptions reverseEngineerOptions)
        {
            var errors = new List<string>();
            var warnings = new List<string>();
            var reporter = new OperationReporter(
                new OperationReportHandler(
                    m => errors.Add(m),
                    m => warnings.Add(m)));

            var serviceProvider = ServiceProviderBuilder.Build(reverseEngineerOptions);
            var scaffolder = serviceProvider.GetService<IReverseEngineerScaffolder>();

            var schemas = new List<string>();
            if (reverseEngineerOptions.DefaultDacpacSchema != null)
            {
                schemas.Add(reverseEngineerOptions.DefaultDacpacSchema);
            }

            if (reverseEngineerOptions.FilterSchemas)
            {
                schemas.AddRange(reverseEngineerOptions.Schemas.Select(s => s.Name));
            }

            var outputDir = !string.IsNullOrEmpty(reverseEngineerOptions.OutputPath)
               ? Path.IsPathFullyQualified(reverseEngineerOptions.OutputPath)
                    ? reverseEngineerOptions.OutputPath
                    : Path.GetFullPath(Path.Combine(reverseEngineerOptions.ProjectPath, reverseEngineerOptions.OutputPath))
                : reverseEngineerOptions.ProjectPath;

            var outputContextDir = !string.IsNullOrEmpty(reverseEngineerOptions.OutputContextPath)
               ? Path.IsPathFullyQualified(reverseEngineerOptions.OutputContextPath)
                    ? reverseEngineerOptions.OutputContextPath
                    : Path.GetFullPath(Path.Combine(reverseEngineerOptions.ProjectPath, reverseEngineerOptions.OutputContextPath))
                : outputDir;

            var modelNamespace = !string.IsNullOrEmpty(reverseEngineerOptions.ModelNamespace)
                ? reverseEngineerOptions.ProjectRootNamespace + "." + reverseEngineerOptions.ModelNamespace
                : PathHelper.GetNamespaceFromOutputPath(outputDir, reverseEngineerOptions.ProjectPath, reverseEngineerOptions.ProjectRootNamespace);

            var contextNamespace = !string.IsNullOrEmpty(reverseEngineerOptions.ContextNamespace)
                ? reverseEngineerOptions.ProjectRootNamespace + "." + reverseEngineerOptions.ContextNamespace
                : PathHelper.GetNamespaceFromOutputPath(outputContextDir, reverseEngineerOptions.ProjectPath, reverseEngineerOptions.ProjectRootNamespace);

            SavedModelFiles procedurePaths = null;
            var procedureModelScaffolder = serviceProvider.GetService<IProcedureScaffolder>();
            if (procedureModelScaffolder != null
                && reverseEngineerOptions.Tables.Where(t => t.ObjectType == RevEng.Shared.ObjectType.Procedure).Count() > 0)
            {
                var procedureOptions = new ProcedureScaffolderOptions
                {
                    ContextDir = outputContextDir,
                    ContextName = reverseEngineerOptions.ContextClassName,
                    ContextNamespace = contextNamespace,
                    ModelNamespace = modelNamespace,
                };

                var procedureModelOptions = new ProcedureModelFactoryOptions
                {
                    FullModel = true,
                    Procedures = reverseEngineerOptions.Tables.Where(t => t.ObjectType == RevEng.Shared.ObjectType.Procedure).Select(m => m.Name),
                };

                var procedureModel = procedureModelScaffolder.ScaffoldModel(reverseEngineerOptions.ConnectionString, procedureOptions, procedureModelOptions, ref errors);

                if (procedureModel != null)
                {
                    procedurePaths = procedureModelScaffolder.Save(
                        procedureModel,
                        Path.GetFullPath(Path.Combine(reverseEngineerOptions.ProjectPath, reverseEngineerOptions.OutputPath ?? string.Empty)),
                        contextNamespace);
                }
            }

            var modelOptions = new ModelReverseEngineerOptions
            {
                UseDatabaseNames = reverseEngineerOptions.UseDatabaseNames,
#if CORE50
                NoPluralize = !reverseEngineerOptions.UseInflector,
#endif
            };

            var codeOptions = new ModelCodeGenerationOptions
            {
                UseDataAnnotations = !reverseEngineerOptions.UseFluentApiOnly,
                Language = "C#",
                ContextName = reverseEngineerOptions.ContextClassName,
                ContextDir = outputContextDir,
                RootNamespace = null,
                ContextNamespace = contextNamespace,
                ModelNamespace = modelNamespace,
                SuppressConnectionStringWarning = false,
                ConnectionString = reverseEngineerOptions.ConnectionString,
#if CORE50
                SuppressOnConfiguring = !reverseEngineerOptions.IncludeConnectionString,
#endif
            };

            var dbOptions = new DatabaseModelFactoryOptions(reverseEngineerOptions.Tables.Where(t => t.ObjectType.HasColumns()).Select(m => m.Name), schemas);

            var scaffoldedModel = scaffolder.ScaffoldModel(
                    reverseEngineerOptions.Dacpac ?? reverseEngineerOptions.ConnectionString,
                    dbOptions,
                    modelOptions,
                    codeOptions);

            var filePaths = scaffolder.Save(
                scaffoldedModel,
                Path.GetFullPath(Path.Combine(reverseEngineerOptions.ProjectPath, reverseEngineerOptions.OutputPath ?? string.Empty)),
                overwriteFiles: true);

#if CORE50
#else
            RemoveOnConfiguring(filePaths.ContextFile, reverseEngineerOptions.IncludeConnectionString);
#endif
            foreach (var file in filePaths.AdditionalFiles)
            {
                PostProcess(file);
            }

            PostProcess(filePaths.ContextFile);

            var entityTypeConfigurationPaths = SplitDbContext(filePaths.ContextFile, reverseEngineerOptions.UseDbContextSplitting, contextNamespace);

            var cleanUpPaths = new SavedModelFiles(filePaths.ContextFile, filePaths.AdditionalFiles);
            if (procedurePaths != null)
            {
                cleanUpPaths.AdditionalFiles.Add(procedurePaths.ContextFile);
                foreach (var additionalFile in procedurePaths.AdditionalFiles)
                {
                    cleanUpPaths.AdditionalFiles.Add(additionalFile);
                }
            }

            CleanUp(cleanUpPaths, entityTypeConfigurationPaths);

            var result = new ReverseEngineerResult
            {
                EntityErrors = errors,
                EntityWarnings = warnings,
                EntityTypeFilePaths = filePaths.AdditionalFiles,
                ContextFilePath = filePaths.ContextFile,
                ContextConfigurationFilePaths = entityTypeConfigurationPaths,
            };

            return result;
        }
Esempio n. 19
0
        public void Issue551Storage()
        {
            // Arrange
            var factory = new SqlServerEdmxDatabaseModelFactory(null);
            var options = new DatabaseModelFactoryOptions(null, new List <string>());

            // Act
            var dbModel = factory.Create(TestPath("AdventureWorks2019.edmx"), options);

            // Assert
            Assert.AreEqual(15, dbModel.Tables.Count());

            // These tables have no FK
            Assert.AreEqual(0, dbModel.Tables.Single(t => t.Name == "BuildVersion").ForeignKeys.Count());
            Assert.AreEqual(0, dbModel.Tables.Single(t => t.Name == "ErrorLog").ForeignKeys.Count());
            Assert.AreEqual(0, dbModel.Tables.Single(t => t.Name == "Address").ForeignKeys.Count());
            Assert.AreEqual(0, dbModel.Tables.Single(t => t.Name == "ProductModel").ForeignKeys.Count());
            Assert.AreEqual(0, dbModel.Tables.Single(t => t.Name == "ProductDescription").ForeignKeys.Count());

            // Views have no foreign key obviously
            Assert.AreEqual(0, dbModel.Tables.Single(t => t.Name == "vProductModelCatalogDescription").ForeignKeys.Count());
            Assert.AreEqual(0, dbModel.Tables.Single(t => t.Name == "vGetAllCategories").ForeignKeys.Count());
            Assert.AreEqual(0, dbModel.Tables.Single(t => t.Name == "vProductAndDescription").ForeignKeys.Count());

            // CustomerAddress
            {
                var customerAddressTable = dbModel.Tables.Single(t => t.Name == "CustomerAddress");
                Assert.AreEqual(5, customerAddressTable.Columns.Count());
                Assert.AreEqual(2, customerAddressTable.ForeignKeys.Count());

                {
                    // FK_CustomerAddress_Address_AddressID
                    var fkCustomerAddressAddressAddressID = customerAddressTable.ForeignKeys.SingleOrDefault(fk => fk.Name == "FK_CustomerAddress_Address_AddressID");
                    Assert.NotNull(fkCustomerAddressAddressAddressID);
                    Assert.NotNull(fkCustomerAddressAddressAddressID.PrincipalTable);
                    Assert.AreEqual("Address", fkCustomerAddressAddressAddressID.PrincipalTable.Name);
                    Assert.AreEqual(1, fkCustomerAddressAddressAddressID.PrincipalColumns.Count());
                    Assert.AreEqual("AddressID", fkCustomerAddressAddressAddressID.PrincipalColumns.First().Name);
                }

                {
                    // FK_CustomerAddress_Customer_CustomerID
                    var fkCustomerAddressCustomerCustomerID = customerAddressTable.ForeignKeys.SingleOrDefault(fk => fk.Name == "FK_CustomerAddress_Customer_CustomerID");
                    Assert.NotNull(fkCustomerAddressCustomerCustomerID);
                    Assert.NotNull(fkCustomerAddressCustomerCustomerID.PrincipalTable);
                    Assert.AreEqual("Customer", fkCustomerAddressCustomerCustomerID.PrincipalTable.Name);
                    Assert.AreEqual(1, fkCustomerAddressCustomerCustomerID.PrincipalColumns.Count());
                    Assert.AreEqual("CustomerID", fkCustomerAddressCustomerCustomerID.PrincipalColumns.First().Name);
                }
            }

            // Product
            {
                var productTable = dbModel.Tables.Single(t => t.Name == "Product");
                Assert.AreEqual(17, productTable.Columns.Count());
                Assert.AreEqual(2, productTable.ForeignKeys.Count());

                {
                    // FK_Product_ProductCategory_ProductCategoryID
                    var fkProductProductCategoryProductCategoryID = productTable.ForeignKeys.SingleOrDefault(fk => fk.Name == "FK_Product_ProductCategory_ProductCategoryID");
                    Assert.NotNull(fkProductProductCategoryProductCategoryID);
                    Assert.NotNull(fkProductProductCategoryProductCategoryID.PrincipalTable);
                    Assert.AreEqual("ProductCategory", fkProductProductCategoryProductCategoryID.PrincipalTable.Name);
                    Assert.AreEqual(1, fkProductProductCategoryProductCategoryID.PrincipalColumns.Count());
                    Assert.AreEqual("ProductCategoryID", fkProductProductCategoryProductCategoryID.PrincipalColumns.First().Name);
                }
                {
                    // FK_Product_ProductModel_ProductModelID
                    var fkProductProductProductModelProductModelID = productTable.ForeignKeys.SingleOrDefault(fk => fk.Name == "FK_Product_ProductModel_ProductModelID");
                    Assert.NotNull(fkProductProductProductModelProductModelID);
                    Assert.NotNull(fkProductProductProductModelProductModelID.PrincipalTable);
                    Assert.AreEqual("ProductModel", fkProductProductProductModelProductModelID.PrincipalTable.Name);
                    Assert.AreEqual(1, fkProductProductProductModelProductModelID.PrincipalColumns.Count());
                    Assert.AreEqual("ProductModelID", fkProductProductProductModelProductModelID.PrincipalColumns.First().Name);
                }
            }

            // ProductModelProductDescription
            {
                var productModelProductDescription = dbModel.Tables.Single(t => t.Name == "ProductModelProductDescription");
                Assert.AreEqual(5, productModelProductDescription.Columns.Count());
                Assert.AreEqual(2, productModelProductDescription.ForeignKeys.Count());
                {
                    {
                        // FK_ProductModelProductDescription_ProductDescription_ProductDescriptionID
                        var fkProductModelProductDescriptionProductDescriptionProductDescriptionID = productModelProductDescription.ForeignKeys.SingleOrDefault(fk => fk.Name == "FK_ProductModelProductDescription_ProductDescription_ProductDescriptionID");
                        Assert.NotNull(fkProductModelProductDescriptionProductDescriptionProductDescriptionID);
                        Assert.NotNull(fkProductModelProductDescriptionProductDescriptionProductDescriptionID.PrincipalTable);
                        Assert.AreEqual("ProductDescription", fkProductModelProductDescriptionProductDescriptionProductDescriptionID.PrincipalTable.Name);
                        Assert.AreEqual(1, fkProductModelProductDescriptionProductDescriptionProductDescriptionID.PrincipalColumns.Count());
                        Assert.AreEqual("ProductDescriptionID", fkProductModelProductDescriptionProductDescriptionProductDescriptionID.PrincipalColumns.First().Name);
                    }
                    {
                        // FK_ProductModelProductDescription_ProductModel_ProductModelID
                        var fkProductModelProductDescriptionProductModelProductModelID = productModelProductDescription.ForeignKeys.SingleOrDefault(fk => fk.Name == "FK_ProductModelProductDescription_ProductModel_ProductModelID");
                        Assert.NotNull(fkProductModelProductDescriptionProductModelProductModelID);
                        Assert.NotNull(fkProductModelProductDescriptionProductModelProductModelID.PrincipalTable);
                        Assert.AreEqual("ProductModel", fkProductModelProductDescriptionProductModelProductModelID.PrincipalTable.Name);
                        Assert.AreEqual(1, fkProductModelProductDescriptionProductModelProductModelID.PrincipalColumns.Count());
                        Assert.AreEqual("ProductModelID", fkProductModelProductDescriptionProductModelProductModelID.PrincipalColumns.First().Name);
                    }
                }
            }

            // SalesOrderDetail
            {
                var salesOrderDetail = dbModel.Tables.Single(t => t.Name == "SalesOrderDetail");
                Assert.AreEqual(9, salesOrderDetail.Columns.Count());
                Assert.AreEqual(2, salesOrderDetail.ForeignKeys.Count());

                {
                    // FK_SalesOrderDetail_Product_ProductID
                    var fkSalesOrderDetailProductProductID = salesOrderDetail.ForeignKeys.SingleOrDefault(fk => fk.Name == "FK_SalesOrderDetail_Product_ProductID");
                    Assert.NotNull(fkSalesOrderDetailProductProductID);
                    Assert.NotNull(fkSalesOrderDetailProductProductID.PrincipalTable);
                    Assert.AreEqual("Product", fkSalesOrderDetailProductProductID.PrincipalTable.Name);
                    Assert.AreEqual(1, fkSalesOrderDetailProductProductID.PrincipalColumns.Count());
                    Assert.AreEqual("ProductID", fkSalesOrderDetailProductProductID.PrincipalColumns.First().Name);
                }

                {
                    // FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID
                    var fkSalesOrderDetailSalesOrderHeaderSalesOrderID = salesOrderDetail.ForeignKeys.SingleOrDefault(fk => fk.Name == "FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID");
                    Assert.NotNull(fkSalesOrderDetailSalesOrderHeaderSalesOrderID);
                    Assert.NotNull(fkSalesOrderDetailSalesOrderHeaderSalesOrderID.PrincipalTable);
                    Assert.AreEqual("SalesOrderHeader", fkSalesOrderDetailSalesOrderHeaderSalesOrderID.PrincipalTable.Name);
                    Assert.AreEqual(1, fkSalesOrderDetailSalesOrderHeaderSalesOrderID.PrincipalColumns.Count());
                    Assert.AreEqual("SalesOrderID", fkSalesOrderDetailSalesOrderHeaderSalesOrderID.PrincipalColumns.First().Name);
                }
            }

            // SalesOrderHeader
            {
                var salesOrderDetail = dbModel.Tables.Single(t => t.Name == "SalesOrderHeader");
                Assert.AreEqual(22, salesOrderDetail.Columns.Count());
                Assert.AreEqual(3, salesOrderDetail.ForeignKeys.Count());

                {
                    // FK_SalesOrderHeader_Address_BillTo_AddressID
                    var fkSalesOrderHeaderAddressBillToAddressID = salesOrderDetail.ForeignKeys.SingleOrDefault(fk => fk.Name == "FK_SalesOrderHeader_Address_BillTo_AddressID");
                    Assert.NotNull(fkSalesOrderHeaderAddressBillToAddressID);
                    Assert.NotNull(fkSalesOrderHeaderAddressBillToAddressID.PrincipalTable);
                    Assert.AreEqual("Address", fkSalesOrderHeaderAddressBillToAddressID.PrincipalTable.Name);
                    Assert.AreEqual(1, fkSalesOrderHeaderAddressBillToAddressID.PrincipalColumns.Count());
                    Assert.AreEqual("AddressID", fkSalesOrderHeaderAddressBillToAddressID.PrincipalColumns.First().Name);
                }

                {
                    // FK_SalesOrderHeader_Address_ShipTo_AddressID
                    var fkSalesOrderHeaderAddressShipToAddressID = salesOrderDetail.ForeignKeys.SingleOrDefault(fk => fk.Name == "FK_SalesOrderHeader_Address_ShipTo_AddressID");
                    Assert.NotNull(fkSalesOrderHeaderAddressShipToAddressID);
                    Assert.NotNull(fkSalesOrderHeaderAddressShipToAddressID.PrincipalTable);
                    Assert.AreEqual("Address", fkSalesOrderHeaderAddressShipToAddressID.PrincipalTable.Name);
                    Assert.AreEqual(1, fkSalesOrderHeaderAddressShipToAddressID.PrincipalColumns.Count());
                    Assert.AreEqual("AddressID", fkSalesOrderHeaderAddressShipToAddressID.PrincipalColumns.First().Name);
                }

                {
                    // FK_SalesOrderHeader_Customer_CustomerID
                    var fkSalesOrderHeaderCustomerCustomerID = salesOrderDetail.ForeignKeys.SingleOrDefault(fk => fk.Name == "FK_SalesOrderHeader_Customer_CustomerID");
                    Assert.NotNull(fkSalesOrderHeaderCustomerCustomerID);
                    Assert.NotNull(fkSalesOrderHeaderCustomerCustomerID.PrincipalTable);
                    Assert.AreEqual("Customer", fkSalesOrderHeaderCustomerCustomerID.PrincipalTable.Name);
                    Assert.AreEqual(1, fkSalesOrderHeaderCustomerCustomerID.PrincipalColumns.Count());
                    Assert.AreEqual("CustomerID", fkSalesOrderHeaderCustomerCustomerID.PrincipalColumns.First().Name);
                }
            }

            // ProductCategory
            {
                var productCategory = dbModel.Tables.Single(t => t.Name == "ProductCategory");
                Assert.AreEqual(5, productCategory.Columns.Count());
                Assert.AreEqual(1, productCategory.ForeignKeys.Count());

                {
                    // FK_ProductCategory_ProductCategory_ParentProductCategoryID_ProductCategoryID
                    var fkProductCategoryProductCategoryParentProductCategoryIDProductCategoryID = productCategory.ForeignKeys.SingleOrDefault(fk => fk.Name == "FK_ProductCategory_ProductCategory_ParentProductCategoryID_ProductCategoryID");
                    Assert.NotNull(fkProductCategoryProductCategoryParentProductCategoryIDProductCategoryID);
                    Assert.NotNull(fkProductCategoryProductCategoryParentProductCategoryIDProductCategoryID.PrincipalTable);
                    Assert.AreEqual("ProductCategory", fkProductCategoryProductCategoryParentProductCategoryIDProductCategoryID.PrincipalTable.Name);
                    Assert.AreEqual(1, fkProductCategoryProductCategoryParentProductCategoryIDProductCategoryID.PrincipalColumns.Count());
                    Assert.AreEqual("ProductCategoryID", fkProductCategoryProductCategoryParentProductCategoryIDProductCategoryID.PrincipalColumns.First().Name);
                    Assert.AreEqual(1, fkProductCategoryProductCategoryParentProductCategoryIDProductCategoryID.Columns.Count());
                    Assert.AreEqual("ParentProductCategoryID", fkProductCategoryProductCategoryParentProductCategoryIDProductCategoryID.Columns.First().Name);
                }
            }
        }
Esempio n. 20
0
            public DatabaseModel Create(string connectionString, DatabaseModelFactoryOptions options)
            {
                ConnectionString = connectionString;

                return(new DatabaseModel());
            }
Esempio n. 21
0
        public DatabaseModel Create(string dacpacPath, DatabaseModelFactoryOptions options)
        {
            if (string.IsNullOrEmpty(dacpacPath))
            {
                throw new ArgumentException(@"invalid path", nameof(dacpacPath));
            }
            if (!File.Exists(dacpacPath))
            {
                throw new ArgumentException("Dacpac file not found");
            }

            var schemas = options.Schemas;
            var tables  = options.Tables;

            var dbModel = new DatabaseModel
            {
                DatabaseName  = Path.GetFileNameWithoutExtension(dacpacPath),
                DefaultSchema = schemas.Count() > 0 ? schemas.First() : "dbo"
            };
            //Sequences not created - not needed for scaffolding

            var consolidator = new DacpacConsolidator();

            dacpacPath = consolidator.Consolidate(dacpacPath);

            var model = new TSqlTypedModel(dacpacPath);

            var typeAliases = GetTypeAliases(model, dbModel);

            var items = model.GetObjects <TSqlTable>(DacQueryScopes.UserDefined)
                        .Where(t => !t.GetProperty <bool>(Table.IsAutoGeneratedHistoryTable))
                        .Where(t => tables == null || !tables.Any() || tables.Contains($"[{t.Name.Parts[0]}].[{t.Name.Parts[1]}]"))
                        .Where(t => $"{t.Name.Parts[1]}" != HistoryRepository.DefaultTableName)
                        .ToList();

            foreach (var item in items)
            {
                var dbTable = new DatabaseTable
                {
                    Name   = item.Name.Parts[1],
                    Schema = item.Name.Parts[0],
                };

                if (item.MemoryOptimized)
                {
                    dbTable["SqlServer:MemoryOptimized"] = true;
                }

                GetColumns(item, dbTable, typeAliases, model.GetObjects <TSqlDefaultConstraint>(DacQueryScopes.UserDefined).ToList());
                GetPrimaryKey(item, dbTable);

                dbModel.Tables.Add(dbTable);
            }

            foreach (var item in items)
            {
                GetForeignKeys(item, dbModel);
                GetUniqueConstraints(item, dbModel);
                GetIndexes(item, dbModel);
            }

            return(dbModel);
        }
Esempio n. 22
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)
        {
            Check.NotEmpty(connectionString, nameof(connectionString));
            Check.NotNull(databaseOptions, nameof(databaseOptions));
            Check.NotNull(modelOptions, nameof(modelOptions));
            Check.NotNull(codeOptions, nameof(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));
        }
Esempio n. 23
0
        public DatabaseModel Create(string dacpacPath, DatabaseModelFactoryOptions options)
        {
            if (string.IsNullOrEmpty(dacpacPath))
            {
                throw new ArgumentException(@"invalid path", nameof(dacpacPath));
            }
            if (!File.Exists(dacpacPath))
            {
                throw new ArgumentException("Dacpac file not found");
            }

            var schemas = options.Schemas;
            var tables  = options.Tables;

            var dbModel = new DatabaseModel
            {
                DatabaseName  = Path.GetFileNameWithoutExtension(dacpacPath),
                DefaultSchema = schemas.Count() > 0 ? schemas.First() : "dbo"
            };

            dbModel["Scaffolding:ConnectionString"] = $"Data Source=(local);Initial Catalog={dbModel.DatabaseName};Integrated Security=true";

            //Sequences not created - not needed for scaffolding

            var consolidator = new DacpacConsolidator();

            dacpacPath = consolidator.Consolidate(dacpacPath);

            var model = new TSqlTypedModel(dacpacPath);

            var typeAliases = GetTypeAliases(model, dbModel);

            var items = model.GetObjects <TSqlTable>(DacQueryScopes.UserDefined)
                        .Where(t => !t.GetProperty <bool>(Table.IsAutoGeneratedHistoryTable))
                        .Where(t => tables == null || !tables.Any() || tables.Contains($"[{t.Name.Parts[0]}].[{t.Name.Parts[1]}]"))
                        .Where(t => $"{t.Name.Parts[1]}" != HistoryRepository.DefaultTableName)
                        .ToList();

            foreach (var item in items)
            {
                var dbTable = new DatabaseTable
                {
                    Name   = item.Name.Parts[1],
                    Schema = item.Name.Parts[0],
                };

                if (item.MemoryOptimized)
                {
                    dbTable["SqlServer:MemoryOptimized"] = true;
                }

                GetColumns(item, dbTable, typeAliases, model.GetObjects <TSqlDefaultConstraint>(DacQueryScopes.UserDefined).ToList(), model);
                GetPrimaryKey(item, dbTable);

                var description = model.GetObjects <TSqlExtendedProperty>(DacQueryScopes.UserDefined)
                                  .Where(p => p.Name.Parts.Count == 4)
                                  .Where(p => p.Name.Parts[0] == "SqlTableBase")
                                  .Where(p => p.Name.Parts[1] == dbTable.Schema)
                                  .Where(p => p.Name.Parts[2] == dbTable.Name)
                                  .Where(p => p.Name.Parts[3] == "MS_Description")
                                  .FirstOrDefault();

                dbTable.Comment = FixExtendedPropertyValue(description?.Value);

                dbModel.Tables.Add(dbTable);
            }

            foreach (var item in items)
            {
                GetForeignKeys(item, dbModel);
                GetUniqueConstraints(item, dbModel);
                GetIndexes(item, dbModel);
            }

            var views = model.GetObjects <TSqlView>(DacQueryScopes.UserDefined)
                        .Where(t => tables == null || !tables.Any() || tables.Contains($"[{t.Name.Parts[0]}].[{t.Name.Parts[1]}]"))
                        .ToList();

            foreach (var view in views)
            {
                var dbView = new DatabaseTable
                {
                    Name   = view.Name.Parts[1],
                    Schema = view.Name.Parts[0],
                };

                GetViewColumns(view, dbView, typeAliases);

                dbModel.Tables.Add(dbView);
            }

            return(dbModel);
        }
Esempio n. 24
0
 public DatabaseModel Create(DbConnection connection, DatabaseModelFactoryOptions options) => throw new NotImplementedException();
Esempio n. 25
0
        public DatabaseModel Create(string edmxPath, DatabaseModelFactoryOptions options)
        {
            if (string.IsNullOrEmpty(edmxPath))
            {
                throw new ArgumentException(@"invalid path", nameof(edmxPath));
            }
            if (!File.Exists(edmxPath))
            {
                throw new ArgumentException($"Edmx file not found: {edmxPath}");
            }

            var schemas = options.Schemas;
            var tables  = options.Tables;

            var dbModel = new DatabaseModel
            {
                DatabaseName  = Path.GetFileNameWithoutExtension(edmxPath),
                DefaultSchema = schemas.Count() > 0 ? schemas.First() : "dbo"
            };

            // Detect the EDMX file version
            XDocument edmxFile = XDocument.Load(edmxPath);

            var edmxVersion = ((XElement)edmxFile.FirstNode).FirstAttribute.Value;

            if (string.Compare(edmxVersion, @"3.0", StringComparison.InvariantCultureIgnoreCase) == 0)
            {
                var edmxv3 = EdmxV3.Load(edmxPath);
                if (!edmxv3.Runtimes[0].StorageModels.StorageSchema.Provider.Equals("System.Data.SqlClient", StringComparison.Ordinal))
                {
                    throw new NotSupportedException("Only SQL Server EDMX files are currently supported");
                }

                var items = edmxv3.GetItems <LinqToEdmx.Model.StorageV3.EntityTypeStore>();

                foreach (var item in items)
                {
                    var dbTable = new DatabaseTable
                    {
                        Name   = item.Name,
                        Schema = GetSchemaNameV3(edmxv3, item.Name),
                    };

                    GetColumnsV3(item, dbTable, edmxv3);
                    GetPrimaryKeyV3(item, dbTable);

                    dbModel.Tables.Add(dbTable);
                }

                foreach (var item in items)
                {
                    GetForeignKeysV3(edmxv3, item, dbModel);
                }
            }
            else
            {
                throw new NotSupportedException("Only V3 edmx files supported.");
            }

            return(dbModel);
        }