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(); } } }
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); }
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)); }
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); }
/// <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(); } } }
/// <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);
/// <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);
public override DatabaseModel Create(string connectionString, DatabaseModelFactoryOptions options) { var connection = new ClickHouseConnection(connectionString); return(Create(connection, options)); }
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(); } }
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(); } }
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); }
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); }
/// <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(); } } }
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; }
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); } } }
public DatabaseModel Create(string connectionString, DatabaseModelFactoryOptions options) { ConnectionString = connectionString; return(new DatabaseModel()); }
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); }
/// <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)); }
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); }
public DatabaseModel Create(DbConnection connection, DatabaseModelFactoryOptions options) => throw new NotImplementedException();
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); }