/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual ScaffoldedModel ScaffoldModel( string connectionString, DatabaseModelFactoryOptions databaseOptions, ModelReverseEngineerOptions modelOptions, ModelCodeGenerationOptions codeOptions) { if (!string.IsNullOrWhiteSpace(codeOptions.ContextName) && (!_cSharpUtilities.IsValidIdentifier(codeOptions.ContextName) || _cSharpUtilities.IsCSharpKeyword(codeOptions.ContextName))) { throw new ArgumentException( DesignStrings.ContextClassNotValidCSharpIdentifier(codeOptions.ContextName)); } var resolvedConnectionString = _connectionStringResolver.ResolveConnectionString(connectionString); if (resolvedConnectionString != connectionString) { codeOptions.SuppressConnectionStringWarning = true; } else if (!codeOptions.SuppressOnConfiguring) { _reporter.WriteWarning(DesignStrings.SensitiveInformationWarning); } if (codeOptions.ConnectionString == null) { codeOptions.ConnectionString = connectionString; } var databaseModel = _databaseModelFactory.Create(resolvedConnectionString, databaseOptions); var modelConnectionString = (string?)(databaseModel[ScaffoldingAnnotationNames.ConnectionString]); if (!string.IsNullOrEmpty(modelConnectionString)) { codeOptions.ConnectionString = modelConnectionString; databaseModel.RemoveAnnotation(ScaffoldingAnnotationNames.ConnectionString); } var model = _factory.Create(databaseModel, modelOptions); if (model == null) { throw new InvalidOperationException( DesignStrings.ProviderReturnedNullModel( _factory.GetType().ShortDisplayName())); } if (string.IsNullOrEmpty(codeOptions.ContextName)) { var annotatedName = model.GetDatabaseName(); codeOptions.ContextName = !string.IsNullOrEmpty(annotatedName) ? _code.Identifier(annotatedName + DbContextSuffix) : DefaultDbContextName; } var codeGenerator = ModelCodeGeneratorSelector.Select(codeOptions.Language); return(codeGenerator.GenerateModel(model, codeOptions)); }
/// <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 IModel Create(DatabaseModel databaseModel, ModelReverseEngineerOptions options) { Check.NotNull(databaseModel, nameof(databaseModel)); Check.NotNull(options, nameof(options)); var modelBuilder = new ModelBuilder(); _tableNamer = new CSharpUniqueNamer <DatabaseTable>( options.UseDatabaseNames ? (Func <DatabaseTable, string>)(t => t.Name) : t => _candidateNamingService.GenerateCandidateIdentifier(t), _cSharpUtilities, options.NoPluralize ? (Func <string, string>)null : _pluralizer.Singularize); _dbSetNamer = new CSharpUniqueNamer <DatabaseTable>( options.UseDatabaseNames ? (Func <DatabaseTable, string>)(t => t.Name) : t => _candidateNamingService.GenerateCandidateIdentifier(t), _cSharpUtilities, options.NoPluralize ? (Func <string, string>)null : _pluralizer.Pluralize); _columnNamers = new Dictionary <DatabaseTable, CSharpUniqueNamer <DatabaseColumn> >(); _options = options; VisitDatabaseModel(modelBuilder, databaseModel); return(modelBuilder.Model); }
private ScaffoldedModel ScaffoldModel( string connectionString, DatabaseModelFactoryOptions databaseOptions, ModelReverseEngineerOptions modelOptions, ModelCodeGenerationOptions codeOptions, bool removeNullableBoolDefaults, bool excludeNavigations, bool dbContextOnly, bool entitiesOnly, bool useSchemaFolders) { var databaseModel = databaseModelFactory.Create(connectionString, databaseOptions); if (removeNullableBoolDefaults) { foreach (var column in databaseModel.Tables .SelectMany(table => table.Columns .Where(column => (column.StoreType == "bit" || column.StoreType == "boolean") && !column.IsNullable && !string.IsNullOrEmpty(column.DefaultValueSql)))) { column.DefaultValueSql = null; } } if (excludeNavigations) { foreach (var table in databaseModel.Tables) { table.ForeignKeys.Clear(); } } #if CORE50 || CORE60 var model = factory.Create(databaseModel, modelOptions); #else var model = factory.Create(databaseModel, modelOptions.UseDatabaseNames); #endif if (model == null) { throw new InvalidOperationException($"No model from provider {factory.GetType().ShortDisplayName()}"); } var codeGenerator = ModelCodeGeneratorSelector.Select(codeOptions.Language); var codeModel = codeGenerator.GenerateModel(model, codeOptions); if (entitiesOnly) { codeModel.ContextFile = null; } if (dbContextOnly) { codeModel.AdditionalFiles.Clear(); } AppendSchemaFolders(model, codeModel, useSchemaFolders); return(codeModel); }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual ScaffoldedModel ScaffoldModel( string connectionString, DatabaseModelFactoryOptions options, string rootNamespace, string modelNamespace, string contextNamespace, string language, string contextDir, string contextName, ModelReverseEngineerOptions modelOptions, ModelCodeGenerationOptions codeOptions) { Check.NotEmpty(connectionString, nameof(connectionString)); Check.NotNull(options, nameof(options)); Check.NotEmpty(modelNamespace, nameof(modelNamespace)); Check.NotEmpty(contextNamespace, nameof(contextNamespace)); Check.NotNull(modelOptions, nameof(modelOptions)); Check.NotNull(codeOptions, nameof(codeOptions)); if (!string.IsNullOrWhiteSpace(contextName) && (!_cSharpUtilities.IsValidIdentifier(contextName) || _cSharpUtilities.IsCSharpKeyword(contextName))) { throw new ArgumentException( DesignStrings.ContextClassNotValidCSharpIdentifier(contextName)); } var resolvedConnectionString = _connectionStringResolver.ResolveConnectionString(connectionString); if (resolvedConnectionString != connectionString) { codeOptions.SuppressConnectionStringWarning = true; } var databaseModel = _databaseModelFactory.Create(resolvedConnectionString, options); var model = _factory.Create(databaseModel, modelOptions.UseDatabaseNames); if (model == null) { throw new InvalidOperationException( DesignStrings.ProviderReturnedNullModel( _factory.GetType().ShortDisplayName())); } if (string.IsNullOrEmpty(contextName)) { contextName = DefaultDbContextName; var annotatedName = model.GetDatabaseName(); if (!string.IsNullOrEmpty(annotatedName)) { contextName = _code.Identifier(annotatedName + DbContextSuffix); } } var codeGenerator = ModelCodeGeneratorSelector.Select(language); return(codeGenerator.GenerateModel(model, rootNamespace, modelNamespace, contextNamespace, contextDir ?? string.Empty, contextName, connectionString, codeOptions)); }
public SavedModelFiles GenerateDbContext( ReverseEngineerCommandOptions options, List <string> schemas, string outputContextDir, string modelNamespace, string contextNamespace) { if (options == null) { throw new ArgumentNullException(nameof(options)); } SavedModelFiles filePaths; var modelOptions = new ModelReverseEngineerOptions { UseDatabaseNames = options.UseDatabaseNames, #if CORE50 || CORE60 NoPluralize = !options.UseInflector, #endif }; var codeOptions = new ModelCodeGenerationOptions { UseDataAnnotations = !options.UseFluentApiOnly, Language = "C#", ContextName = code.Identifier(options.ContextClassName), ContextDir = outputContextDir, RootNamespace = null, ContextNamespace = contextNamespace, ModelNamespace = modelNamespace, SuppressConnectionStringWarning = false, ConnectionString = options.ConnectionString, #if CORE50 || CORE60 SuppressOnConfiguring = !options.IncludeConnectionString, #endif #if CORE60 UseNullableReferenceTypes = options.UseNullableReferences, #endif }; var dbOptions = new DatabaseModelFactoryOptions(options.Tables.Where(t => t.ObjectType.HasColumns()).Select(m => m.Name), schemas); var scaffoldedModel = ScaffoldModel( options.Dacpac ?? options.ConnectionString, dbOptions, modelOptions, codeOptions, options.UseBoolPropertiesWithoutDefaultSql, options.UseNoNavigations, options.SelectedToBeGenerated == 1, // DbContext only options.SelectedToBeGenerated == 2, // Entities only options.UseSchemaFolders); filePaths = Save( scaffoldedModel, Path.GetFullPath(Path.Combine(options.ProjectPath, options.OutputPath ?? string.Empty))); return(filePaths); }
public override IModel Create(DatabaseModel databaseModel, ModelReverseEngineerOptions options) { foreach (var sequence in databaseModel.Sequences) { sequence.Database = databaseModel; } foreach (var table in databaseModel.Tables) { table.Database = databaseModel; foreach (var column in table.Columns) { column.Table = table; } if (table.PrimaryKey != null) { table.PrimaryKey.Table = table; FixupColumns(table, table.PrimaryKey.Columns); } foreach (var index in table.Indexes) { index.Table = table; FixupColumns(table, index.Columns); } foreach (var uniqueConstraints in table.UniqueConstraints) { uniqueConstraints.Table = table; FixupColumns(table, uniqueConstraints.Columns); } foreach (var foreignKey in table.ForeignKeys) { foreignKey.Table = table; FixupColumns(table, foreignKey.Columns); if (foreignKey.PrincipalTable is DatabaseTableRef tableRef) { foreignKey.PrincipalTable = databaseModel.Tables .First(t => t.Name == tableRef.Name && t.Schema == tableRef.Schema); } FixupColumns(foreignKey.PrincipalTable, foreignKey.PrincipalColumns); } } return(base.Create(databaseModel, options)); }
private static ScaffoldedModel ScaffoldModel( string connectionString, DatabaseModelFactoryOptions databaseOptions, ModelReverseEngineerOptions modelOptions, ModelCodeGenerationOptions codeOptions, bool removeNullableBoolDefaults, bool excludeNavigations, 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 (excludeNavigations) { foreach (var table in databaseModel.Tables) { table.ForeignKeys.Clear(); } } #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)); }
// // 摘要: // /// This API supports the Entity Framework Core infrastructure and is not intended // to be used /// directly from your code. This API may change or be removed in // future releases. /// public override ScaffoldedModel ScaffoldModel(string connectionString, IEnumerable <string> tables, IEnumerable <string> schemas, string @namespace, string language, string contextDir, string contextName, ModelReverseEngineerOptions modelOptions, ModelCodeGenerationOptions codeOptions) { if (tables == null || !tables.Any()) { tables = HandlebarsScaffoldingOptions.Tables ?? new List <string>(); } if (schemas == null || !schemas.Any()) { schemas = HandlebarsScaffoldingOptions.Schemas ?? new List <string>(); } return(base.ScaffoldModel(connectionString, tables, schemas, @namespace, language, contextDir, contextName, modelOptions, codeOptions)); }
public override IModel Create(DatabaseModel databaseModel, ModelReverseEngineerOptions options) { foreach (var sequence in databaseModel.Sequences) { sequence.Database = databaseModel; } foreach (var table in databaseModel.Tables) { table.Database = databaseModel; foreach (var column in table.Columns) { column.Table = table; } if (table.PrimaryKey != null) { table.PrimaryKey.Table = table; } foreach (var index in table.Indexes) { index.Table = table; } foreach (var uniqueConstraints in table.UniqueConstraints) { uniqueConstraints.Table = table; } foreach (var foreignKey in table.ForeignKeys) { foreignKey.Table = table; } } return(base.Create(databaseModel, options)); }
public EfCoreReverseEngineerResult GenerateFiles(ReverseEngineerOptions 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))); // Add base services for scaffolding var serviceCollection = new ServiceCollection(); serviceCollection .AddEntityFrameworkDesignTimeServices() .AddSingleton <IOperationReporter, OperationReporter>() .AddSingleton <IOperationReportHandler, OperationReportHandler>(); if (reverseEngineerOptions.UseHandleBars) { //TODO Consider being selective based on SelectedToBeGenerated serviceCollection.AddHandlebarsScaffolding(); serviceCollection.AddSingleton <ITemplateFileService>(provider => new CustomTemplateFileService(reverseEngineerOptions.ProjectPath)); } if (reverseEngineerOptions.CustomReplacers != null) { serviceCollection.AddSingleton <ICandidateNamingService>(provider => new ReplacingCandidateNamingService(reverseEngineerOptions.CustomReplacers)); } if (reverseEngineerOptions.UseInflector) { serviceCollection.AddSingleton <IPluralizer, InflectorPluralizer>(); } // Add database provider services switch (reverseEngineerOptions.DatabaseType) { case DatabaseType.SQLCE35: throw new NotImplementedException(); case DatabaseType.SQLCE40: var sqlCeProvider = new SqlCeDesignTimeServices(); sqlCeProvider.ConfigureDesignTimeServices(serviceCollection); break; case DatabaseType.SQLServer: var provider = new SqlServerDesignTimeServices(); provider.ConfigureDesignTimeServices(serviceCollection); var spatial = new SqlServerNetTopologySuiteDesignTimeServices(); spatial.ConfigureDesignTimeServices(serviceCollection); if (!string.IsNullOrEmpty(reverseEngineerOptions.Dacpac)) { serviceCollection.AddSingleton <IDatabaseModelFactory, SqlServerDacpacDatabaseModelFactory>(); } break; case DatabaseType.Npgsql: var npgsqlProvider = new NpgsqlDesignTimeServices(); npgsqlProvider.ConfigureDesignTimeServices(serviceCollection); break; case DatabaseType.Mysql: var mysqlProvider = new MySqlDesignTimeServices(); mysqlProvider.ConfigureDesignTimeServices(serviceCollection); break; case DatabaseType.SQLite: var sqliteProvider = new SqliteDesignTimeServices(); sqliteProvider.ConfigureDesignTimeServices(serviceCollection); break; default: throw new ArgumentOutOfRangeException(); } var serviceProvider = serviceCollection.BuildServiceProvider(); var scaffolder = serviceProvider.GetService <IReverseEngineerScaffolder>(); var schemas = new List <string>(); if (reverseEngineerOptions.DefaultDacpacSchema != null) { schemas.Add(reverseEngineerOptions.DefaultDacpacSchema); } var @namespace = reverseEngineerOptions.ProjectRootNamespace; if (!string.IsNullOrEmpty(reverseEngineerOptions.OutputPath)) { @namespace += "." + reverseEngineerOptions.OutputPath.Replace(Path.DirectorySeparatorChar, '.').Replace(Path.AltDirectorySeparatorChar, '.'); } var modelOptions = new ModelReverseEngineerOptions { UseDatabaseNames = reverseEngineerOptions.UseDatabaseNames }; var codeOptions = new ModelCodeGenerationOptions { UseDataAnnotations = !reverseEngineerOptions.UseFluentApiOnly }; var scaffoldedModel = scaffolder.ScaffoldModel( reverseEngineerOptions.Dacpac != null ? reverseEngineerOptions.Dacpac : reverseEngineerOptions.ConnectionString, reverseEngineerOptions.Tables.Select(m => m.Name).ToArray(), schemas, @namespace, "C#", null, reverseEngineerOptions.ContextClassName, modelOptions, codeOptions); var filePaths = scaffolder.Save( scaffoldedModel, Path.Combine(reverseEngineerOptions.ProjectPath, reverseEngineerOptions.OutputPath ?? string.Empty), overwriteFiles: true); PostProcessContext(filePaths.ContextFile, reverseEngineerOptions); foreach (var file in filePaths.AdditionalFiles) { PostProcess(file, reverseEngineerOptions.IdReplace); } PostProcess(filePaths.ContextFile, reverseEngineerOptions.IdReplace); var result = new EfCoreReverseEngineerResult { EntityErrors = errors, EntityWarnings = warnings, EntityTypeFilePaths = filePaths.AdditionalFiles, ContextFilePath = filePaths.ContextFile, }; return(result); }
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 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); }
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(); } }
public ReverseEngineerResult GenerateFiles(ReverseEngineerOptions reverseEngineerOptions, bool includeViews) { if (includeViews) { return(LaunchExternalRunner(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.GetFullPath(Path.Combine(reverseEngineerOptions.ProjectPath, reverseEngineerOptions.OutputPath)) : reverseEngineerOptions.ProjectPath; var outputContextDir = !string.IsNullOrEmpty(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 }; var scaffoldedModel = scaffolder.ScaffoldModel( reverseEngineerOptions.Dacpac != null ? reverseEngineerOptions.Dacpac : reverseEngineerOptions.ConnectionString, reverseEngineerOptions.Tables.Select(m => m.Name).ToArray(), schemas, modelNamespace, "C#", outputContextDir, reverseEngineerOptions.ContextClassName, modelOptions, codeOptions); var filePaths = scaffolder.Save( scaffoldedModel, outputDir, overwriteFiles: true); PostProcessContext(filePaths.ContextFile, reverseEngineerOptions, modelNamespace, contextNamespace); foreach (var file in filePaths.AdditionalFiles) { PostProcess(file, reverseEngineerOptions.IdReplace); } PostProcess(filePaths.ContextFile, reverseEngineerOptions.IdReplace); CleanUp(filePaths); var result = new ReverseEngineerResult { EntityErrors = errors, EntityWarnings = warnings, EntityTypeFilePaths = filePaths.AdditionalFiles, ContextFilePath = filePaths.ContextFile, }; return(result); }
public EfCoreReverseEngineerResult GenerateFiles(ReverseEngineerOptions 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 @namespace = reverseEngineerOptions.ProjectRootNamespace; if (!string.IsNullOrEmpty(reverseEngineerOptions.OutputPath) && !reverseEngineerOptions.DoNotCombineNamespace) { @namespace += "." + reverseEngineerOptions.OutputPath.Replace(Path.DirectorySeparatorChar, '.').Replace(Path.AltDirectorySeparatorChar, '.'); } var modelOptions = new ModelReverseEngineerOptions { UseDatabaseNames = reverseEngineerOptions.UseDatabaseNames }; var codeOptions = new ModelCodeGenerationOptions { UseDataAnnotations = !reverseEngineerOptions.UseFluentApiOnly }; var scaffoldedModel = scaffolder.ScaffoldModel( reverseEngineerOptions.Dacpac != null ? reverseEngineerOptions.Dacpac : reverseEngineerOptions.ConnectionString, reverseEngineerOptions.Tables.Select(m => m.Name).ToArray(), schemas, @namespace, "C#", null, reverseEngineerOptions.ContextClassName, modelOptions, codeOptions); var filePaths = scaffolder.Save( scaffoldedModel, Path.Combine(reverseEngineerOptions.ProjectPath, reverseEngineerOptions.OutputPath ?? string.Empty), overwriteFiles: true); PostProcessContext(filePaths.ContextFile, reverseEngineerOptions); foreach (var file in filePaths.AdditionalFiles) { PostProcess(file, reverseEngineerOptions.IdReplace); } PostProcess(filePaths.ContextFile, reverseEngineerOptions.IdReplace); var result = new EfCoreReverseEngineerResult { EntityErrors = errors, EntityWarnings = warnings, EntityTypeFilePaths = filePaths.AdditionalFiles, ContextFilePath = filePaths.ContextFile, }; return(result); }
//public ScaffoldedModel ScaffoldModel(string connectionString, IEnumerable<string> tables, IEnumerable<string> schemas, string @namespace, // string language, string contextDir, string contextName, ModelReverseEngineerOptions modelOptions, // ModelCodeGenerationOptions codeOptions) //{ // var fullTables = tables.Select(x => new EntityType { FileName = x, DisplayName = x, Name = x }).ToList(); // return ScaffoldModel(connectionString, fullTables, schemas, @namespace, language, contextDir, contextName, // modelOptions, codeOptions); //} public ScaffoldedModel ScaffoldModel(string connectionString, [NoEnumeration] IEnumerable <EntityType> tables, IEnumerable <string> schemas, string @namespace, string language, string contextDir, string contextName, ModelReverseEngineerOptions modelOptions, ModelCodeGenerationOptions codeOptions) { var entityTypes = tables.ToList(); var resolvedConnectionString = _connectionStringResolver.ResolveConnectionString(connectionString); if (resolvedConnectionString != connectionString) { codeOptions.SuppressConnectionStringWarning = true; } var databaseModel = _databaseModelFactory.Create(resolvedConnectionString, entityTypes.Select(x => x.Name).ToList(), schemas); var customDatabaseModel = CreateCustomDatabaseModel(databaseModel, entityTypes); var model = _scaffoldingModelFactory.Create(customDatabaseModel, modelOptions.UseDatabaseNames); if (model == null) { // TODO: thow some other proper exception throw new Exception("Model is null"); //throw new InvalidOperationException( // DesignStrings.ProviderReturnedNullModel( // _factory.GetType().ShortDisplayName())); } // TODO: Handle what to do when the contextName is empty //if (string.IsNullOrEmpty(contextName)) //{ // contextName = DefaultDbContextName; // var annotatedName = model.Scaffolding().DatabaseName; // if (!string.IsNullOrEmpty(annotatedName)) // { // contextName = _cSharpHelper.Identifier(annotatedName + DbContextSuffix); // } //} var codeGenerator = _modelCodeGeneratorSelector.Select(language); return(codeGenerator.GenerateModel(model, @namespace, contextDir ?? string.Empty, contextName, connectionString, codeOptions)); }