/// <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)); }
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); }
protected void Test( Action <ModelBuilder> buildModel, ModelCodeGenerationOptions options, Action <ScaffoldedModel> assertScaffold) { Test(buildModel, options, assertScaffold, null); }
public override ScaffoldedModel GenerateModel(IModel model, string @namespace, string contextDir, string contextName, string connectionString, ModelCodeGenerationOptions options) { EntityTypeConfigurationTemplateService.RegisterPartialTemplates(); var resultingFiles = base.GenerateModel(model, @namespace, contextDir, contextName, connectionString, options); string generatedCode; if (!(CSharpEntityTypeConfigurationGenerator is NullCSharpEntityTypeConfigurationGenerator)) { foreach (var entityType in model.GetEntityTypes()) { generatedCode = CSharpEntityTypeConfigurationGenerator.WriteCode(entityType, @namespace, options.UseDataAnnotations); var transformedFileName = EntityTypeTransformationService.TransformEntityTypeConfigurationFileName(entityType.DisplayName(), HandlebarsScaffoldingOptions.EntityTypeConfigurationFileNameSuffix); var entityTypeCfgFileName = transformedFileName + FileExtension; resultingFiles.AdditionalFiles.Add(new ScaffoldedFile { Path = Path.Combine(contextDir, contextName + HandlebarsScaffoldingOptions.EntityTypeConfigurationDirSuffix, entityTypeCfgFileName), Code = generatedCode }); } } return(resultingFiles); }
protected void Test( Action <ModelBuilder> buildModel, ModelCodeGenerationOptions options, Action <ScaffoldedModel> assertScaffold) { var designServices = new ServiceCollection(); AddModelServices(designServices); var modelBuilder = SqlServerTestHelpers.Instance.CreateConventionBuilder(customServices: designServices); modelBuilder.Model.RemoveAnnotation(CoreAnnotationNames.ProductVersion); buildModel(modelBuilder); var model = modelBuilder.FinalizeModel(designTime: true, skipValidation: true); var services = CreateServices(); AddScaffoldingServices(services); var generator = services.BuildServiceProvider(validateScopes: true) .GetRequiredService <IModelCodeGenerator>(); options.ModelNamespace ??= "TestNamespace"; options.ContextName = "TestDbContext"; options.ConnectionString = "Initial Catalog=TestDatabase"; var scaffoldedModel = generator.GenerateModel( model, options); assertScaffold(scaffoldedModel); }
/// <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)); }
protected void Test( Action <ModelBuilder> buildModel, ModelCodeGenerationOptions options, Action <ScaffoldedModel> assertScaffold, Action <IModel> assertModel) { var modelBuilder = SqlServerTestHelpers.Instance.CreateConventionBuilder(); modelBuilder.Model.RemoveAnnotation(CoreAnnotationNames.ProductVersion); buildModel(modelBuilder); var model = modelBuilder.FinalizeModel(); var services = new ServiceCollection() .AddEntityFrameworkDesignTimeServices(); new SqlServerDesignTimeServices().ConfigureDesignTimeServices(services); var generator = services .BuildServiceProvider() .GetRequiredService <IModelCodeGenerator>(); options.ModelNamespace ??= "TestNamespace"; options.ContextName = "TestDbContext"; options.ConnectionString = "Initial Catalog=TestDatabase"; var scaffoldedModel = generator.GenerateModel( model, options); assertScaffold(scaffoldedModel); var build = new BuildSource { References = { BuildReference.ByName("Microsoft.EntityFrameworkCore.Abstractions"), BuildReference.ByName("Microsoft.EntityFrameworkCore"), BuildReference.ByName("Microsoft.EntityFrameworkCore.Relational"), BuildReference.ByName("Microsoft.EntityFrameworkCore.SqlServer") }, Sources = new List <string>( new[] { scaffoldedModel.ContextFile.Code }.Concat( scaffoldedModel.AdditionalFiles.Select(f => f.Code))) }; var assembly = build.BuildInMemory(); var contextNamespace = options.ContextNamespace ?? options.ModelNamespace; var context = (DbContext)assembly.CreateInstance( !string.IsNullOrEmpty(contextNamespace) ? contextNamespace + "." + options.ContextName : options.ContextName); if (assertModel != null) { var compiledModel = context.Model; assertModel(compiledModel); } }
public override ScaffoldedModel GenerateModel( IModel model, ModelCodeGenerationOptions options) { Check.NotNull(model, nameof(model)); Check.NotNull(options, nameof(options)); if (options.ContextName == null) { throw new ArgumentException(CoreStrings.ArgumentPropertyNull(nameof(options.ContextName), nameof(options)), nameof(options)); } if (options.ConnectionString == null) { throw new ArgumentException(CoreStrings.ArgumentPropertyNull(nameof(options.ConnectionString), nameof(options)), nameof(options)); } if (options.ModelNamespace == null) { throw new ArgumentException(CoreStrings.ArgumentPropertyNull(nameof(options.ModelNamespace), nameof(options)), nameof(options)); } var generatedCode = CSharpDbContextGenerator.WriteCode( model, options.ContextName, options.ConnectionString, options.ContextNamespace, options.ModelNamespace, options.UseDataAnnotations, options.SuppressConnectionStringWarning, options.SuppressOnConfiguring); // output DbContext .cs file var dbContextFileName = options.ContextName + FileExtension; var resultingFiles = new ScaffoldedModel { ContextFile = new ScaffoldedFile { Path = options.ContextDir != null ? Path.Combine(options.ContextDir, dbContextFileName) : dbContextFileName, Code = generatedCode } }; foreach (var entityType in model.GetEntityTypes()) { generatedCode = CSharpEntityTypeGenerator.WriteCode(entityType, options.ModelNamespace, options.UseDataAnnotations); // output EntityType poco .cs file var entityTypeFileName = entityType.DisplayName() + FileExtension; resultingFiles.AdditionalFiles.Add( new ScaffoldedFile { Path = entityTypeFileName, Code = generatedCode }); } return(resultingFiles); }
/// <summary> /// <summary>Generates code for a model.</summary> /// </summary> /// <param name="model"> The model.</param> /// <param name="options"> The options to use during generation. </param> /// <returns> The generated model. </returns> public override ScaffoldedModel GenerateModel(IModel model, ModelCodeGenerationOptions options) { Check.NotNull(model, nameof(model)); Check.NotNull(options, nameof(options)); // Register Hbs helpers and partial templates HandlebarsHelperService.RegisterHelpers(); HandlebarsBlockHelperService.RegisterBlockHelpers(); DbContextTemplateService.RegisterPartialTemplates(); EntityTypeTemplateService.RegisterPartialTemplates(); var resultingFiles = new ScaffoldedModel(); string generatedCode; if (!(CSharpDbContextGenerator is NullCSharpDbContextGenerator)) { generatedCode = CSharpDbContextGenerator.WriteCode( model, options.ContextName, options.ConnectionString, options.ContextNamespace, options.ModelNamespace, options.UseDataAnnotations, options.SuppressConnectionStringWarning); var dbContextFileName = options.ContextName + FileExtension; resultingFiles.ContextFile = new ScaffoldedFile { Path = options.ContextDir != null ? Path.Combine(options.ContextDir, dbContextFileName) : dbContextFileName, Code = generatedCode }; } if (!(CSharpEntityTypeGenerator is NullCSharpEntityTypeGenerator)) { foreach (var entityType in model.GetScaffoldEntityTypes(_options.Value)) { generatedCode = CSharpEntityTypeGenerator.WriteCode( entityType, options.ModelNamespace, options.UseDataAnnotations); var transformedFileName = EntityTypeTransformationService.TransformEntityFileName(entityType.DisplayName()); var entityTypeFileName = transformedFileName + FileExtension; resultingFiles.AdditionalFiles.Add( new ScaffoldedFile { Path = entityTypeFileName, Code = generatedCode }); } } return(resultingFiles); }
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); }
protected void Test( Action <ModelBuilder> buildModel, ModelCodeGenerationOptions options, Action <ScaffoldedModel> assertScaffold, Action <IModel> assertModel) { var modelBuilder = new ModelBuilder(BuildNonValidatingConventionSet()); modelBuilder.Model.RemoveAnnotation(CoreAnnotationNames.ProductVersionAnnotation); buildModel(modelBuilder); var _ = modelBuilder.Model.Scaffolding().EntityTypeErrors; var model = modelBuilder.FinalizeModel(); var services = new ServiceCollection() .AddEntityFrameworkDesignTimeServices(); new SqlServerDesignTimeServices().ConfigureDesignTimeServices(services); var generator = services .BuildServiceProvider() .GetRequiredService <IModelCodeGenerator>(); var scaffoldedModel = generator.GenerateModel( model, "TestNamespace", "TestNamespace", "TestNamespace", /*contextDir:*/ string.Empty, "TestDbContext", "Initial Catalog=TestDatabase", options); assertScaffold(scaffoldedModel); var build = new BuildSource { References = { BuildReference.ByName("Microsoft.EntityFrameworkCore"), BuildReference.ByName("Microsoft.EntityFrameworkCore.Relational"), BuildReference.ByName("Microsoft.EntityFrameworkCore.SqlServer") }, Sources = new List <string>( new[] { scaffoldedModel.ContextFile.Code }.Concat( scaffoldedModel.AdditionalFiles.Select(f => f.Code))) }; var assembly = build.BuildInMemory(); var context = (DbContext)assembly.CreateInstance("TestNamespace.TestDbContext"); var compiledModel = context.Model; assertModel(compiledModel); }
private void Test( Action <ModelBuilder> buildModel, ModelCodeGenerationOptions options, Action <ScaffoldedModel> assertScaffold, Action <IModel> assertModel) { var modelBuilder = new ModelBuilder(SqlServerConventionSetBuilder.Build()); buildModel(modelBuilder); modelBuilder.GetInfrastructure().Metadata.Validate(); var model = modelBuilder.Model; var services = new ServiceCollection() .AddEntityFrameworkDesignTimeServices(); new SqlServerDesignTimeServices().ConfigureDesignTimeServices(services); var generator = services .BuildServiceProvider() .GetRequiredService <IModelCodeGenerator>(); var scaffoldedModel = generator.GenerateModel( model, "TestNamespace", /*contextDir:*/ string.Empty, "TestDbContext", "Initial Catalog=TestDatabase", options); assertScaffold(scaffoldedModel); var build = new BuildSource { References = { BuildReference.ByName("Microsoft.EntityFrameworkCore"), BuildReference.ByName("Microsoft.EntityFrameworkCore.Relational"), BuildReference.ByName("Microsoft.EntityFrameworkCore.SqlServer") }, Sources = new List <string>( Enumerable.Concat( new[] { scaffoldedModel.ContextFile.Code }, scaffoldedModel.AdditionalFiles.Select(f => f.Code))) }; var assembly = build.BuildInMemory(); var context = (DbContext)assembly.CreateInstance("TestNamespace.TestDbContext"); var compiledModel = context.Model; assertModel(compiledModel); }
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)); }
public void ModelSameNamespaceDbContext_works() { var modelGenerationOptions = new ModelCodeGenerationOptions { ContextNamespace = "TestNamespace" }; const string entityInAnotherNamespaceTypeName = "EntityInAnotherNamespace"; Test( modelBuilder => modelBuilder.Entity(entityInAnotherNamespaceTypeName) , modelGenerationOptions , code => Assert.DoesNotContain(string.Concat("using ", modelGenerationOptions.ModelNamespace, ";"), code.ContextFile.Code) , model => Assert.NotNull(model.FindEntityType(string.Concat(modelGenerationOptions.ModelNamespace, ".", entityInAnotherNamespaceTypeName))) ); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public override ScaffoldedModel GenerateModel( IModel model, string rootNamespace, string modelNamespace, string contextNamespace, string contextDir, string contextName, string connectionString, ModelCodeGenerationOptions options) { Check.NotNull(model, nameof(model)); Check.NotEmpty(modelNamespace, nameof(modelNamespace)); Check.NotEmpty(contextNamespace, nameof(contextNamespace)); Check.NotNull(contextDir, nameof(contextDir)); Check.NotEmpty(contextName, nameof(contextName)); Check.NotEmpty(connectionString, nameof(connectionString)); Check.NotNull(options, nameof(options)); var resultingFiles = new ScaffoldedModel(); var generatedCode = CSharpDbContextGenerator.WriteCode(model, contextNamespace, contextName, connectionString, options.UseDataAnnotations, options.SuppressConnectionStringWarning); // output DbContext .cs file var dbContextFileName = contextName + FileExtension; resultingFiles.ContextFile = new ScaffoldedFile { Path = Path.Combine(contextDir, dbContextFileName), Code = generatedCode }; foreach (var entityType in model.GetEntityTypes()) { generatedCode = CSharpEntityTypeGenerator.WriteCode(entityType, modelNamespace, options.UseDataAnnotations); // output EntityType poco .cs file var entityTypeFileName = ((ITypeBase)entityType).DisplayName() + FileExtension; resultingFiles.AdditionalFiles.Add( new ScaffoldedFile { Path = entityTypeFileName, Code = generatedCode }); } return(resultingFiles); }
public void Select_throws_when_no_service_for_language() { var selector = new ModelCodeGeneratorSelector( new[] { new TestModelCodeGenerator("C#") }); var options = new ModelCodeGenerationOptions { Language = "VB" }; var ex = Assert.Throws <OperationException>( () => selector.Select(options)); Assert.Equal(DesignStrings.NoLanguageService("VB", nameof(IModelCodeGenerator)), ex.Message); }
//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)); }
// // 摘要: // /// 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)); }
/// <summary> /// Generates code for a model. /// </summary> /// <param name="model">The model.</param> /// <param name="options">The model generatation options <see cref="ModelCodeGenerationOptions"/>.</param> /// <returns></returns> public ScaffoldedModel GenerateModel(IModel model, ModelCodeGenerationOptions options) { var files = new ScaffoldedModel(); var contextCode = this.dbContextGenerator.WriteCode( model, options.ContextNamespace, options.ContextName, options.ConnectionString, options.UseDataAnnotations, options.SuppressConnectionStringWarning ); files.ContextFile = new ScaffoldedFile { Path = Path.Combine(options.ContextDir, options.ContextName + FileExtension), Code = contextCode }; foreach (var entityType in model.GetEntityTypes()) { var entityCode = this.entityTypeGenerator.WriteCode( entityType, options.ContextNamespace, options.UseDataAnnotations ); var entityFile = new ScaffoldedFile { Path = entityType.DisplayName() + FileExtension, Code = entityCode }; files.AdditionalFiles.Add(entityFile); } return(files); }
public override ScaffoldedModel GenerateModel(IModel model, ModelCodeGenerationOptions options) { var resultingFiles = new ScaffoldedModel(); var contextGenerator = new MyDbContextGenerator { Session = new Dictionary <string, object> { ["Model"] = model, ["ModelNamespace"] = options.ModelNamespace, ["Namespace"] = options.ContextNamespace, ["ContextName"] = options.ContextName, ["ConnectionString"] = options.ConnectionString, ["SuppressConnectionStringWarning"] = options.SuppressConnectionStringWarning, ["UseDataAnnotations"] = options.UseDataAnnotations, ["Code"] = _csharpHelper, ["ProviderCode"] = _providerConfigurationCodeGenerator, ["AnnotationCode"] = _annotationCodeGenerator } }; contextGenerator.Initialize(); var generatedCode = contextGenerator.TransformText(); var dbContextFileName = options.ContextName + ".cs"; resultingFiles.ContextFile = new ScaffoldedFile { Path = Path.Combine(options.ContextDir, dbContextFileName), Code = generatedCode }; foreach (var entityType in model.GetEntityTypes()) { var entityGenerator = new MyEntityTypeGenerator { Session = new Dictionary <string, object> { ["EntityType"] = entityType, ["Namespace"] = options.ModelNamespace, ["UseDataAnnotations"] = options.UseDataAnnotations, ["Code"] = _csharpHelper } }; entityGenerator.Initialize(); generatedCode = entityGenerator.TransformText(); resultingFiles.AdditionalFiles.Add( new ScaffoldedFile { Path = entityType.Name + ".cs", Code = generatedCode }); var configurationGenerator = new MyEntityTypeConfigurationGenerator { Session = new Dictionary <string, object> { ["EntityType"] = entityType, ["ModelNamespace"] = options.ModelNamespace, ["Namespace"] = options.ContextNamespace, ["UseDataAnnotations"] = options.UseDataAnnotations, ["Code"] = _csharpHelper, ["AnnotationCode"] = _annotationCodeGenerator } }; configurationGenerator.Initialize(); generatedCode = configurationGenerator.TransformText(); resultingFiles.AdditionalFiles.Add( new ScaffoldedFile { Path = Path.Combine(options.ContextDir, entityType.Name + "Configuration.cs"), Code = generatedCode }); } return(resultingFiles); }
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 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); }
protected void Test( Action <ModelBuilder> buildModel, ModelCodeGenerationOptions options, Action <ScaffoldedModel> assertScaffold, Action <IModel> assertModel, bool skipBuild = false) { var designServices = new ServiceCollection(); AddModelServices(designServices); var modelBuilder = SqlServerTestHelpers.Instance.CreateConventionBuilder(customServices: designServices); modelBuilder.Model.RemoveAnnotation(CoreAnnotationNames.ProductVersion); buildModel(modelBuilder); var model = modelBuilder.FinalizeModel(designTime: true, skipValidation: true); var services = CreateServices(); AddScaffoldingServices(services); var generator = services.BuildServiceProvider(validateScopes: true) .GetRequiredService <IModelCodeGenerator>(); options.ModelNamespace ??= "TestNamespace"; options.ContextName = "TestDbContext"; options.ConnectionString = "Initial Catalog=TestDatabase"; var scaffoldedModel = generator.GenerateModel( model, options); assertScaffold(scaffoldedModel); var build = new BuildSource { References = { BuildReference.ByName("Microsoft.EntityFrameworkCore.Abstractions"), BuildReference.ByName("Microsoft.EntityFrameworkCore"), BuildReference.ByName("Microsoft.EntityFrameworkCore.Relational"), BuildReference.ByName("Microsoft.EntityFrameworkCore.SqlServer") }, Sources = new[] { scaffoldedModel.ContextFile }.Concat(scaffoldedModel.AdditionalFiles) .ToDictionary(f => f.Path, f => f.Code), NullableReferenceTypes = options.UseNullableReferenceTypes }; if (!skipBuild) { var assembly = build.BuildInMemory(); if (assertModel != null) { var contextNamespace = options.ContextNamespace ?? options.ModelNamespace; var context = (DbContext)assembly.CreateInstance( !string.IsNullOrEmpty(contextNamespace) ? contextNamespace + "." + options.ContextName : options.ContextName); var compiledModel = context.GetService <IDesignTimeModel>().Model; assertModel(compiledModel); } } }
/// <summary>Generates code for a model.</summary> /// <param name="model"> The model. </param> /// <param name="namespace"> The namespace. </param> /// <param name="contextDir"> The directory of the <see cref="T:Microsoft.EntityFrameworkCore.DbContext" />. </param> /// <param name="contextName"> The name of the <see cref="T:Microsoft.EntityFrameworkCore.DbContext" />. </param> /// <param name="connectionString"> The connection string. </param> /// <param name="options"> The options to use during generation. </param> /// <returns> The generated model. </returns> public override ScaffoldedModel GenerateModel(IModel model, string @namespace, string contextDir, string contextName, string connectionString, ModelCodeGenerationOptions options) { if (model == null) { throw new ArgumentNullException(nameof(model)); } if (string.IsNullOrWhiteSpace(@namespace)) { throw new ArgumentNullException(nameof(@namespace)); } if (contextDir == null) { throw new ArgumentNullException(nameof(contextDir)); } if (string.IsNullOrWhiteSpace(contextName)) { throw new ArgumentNullException(nameof(contextName)); } if (string.IsNullOrWhiteSpace(connectionString)) { throw new ArgumentNullException(nameof(connectionString)); } if (contextDir == null) { throw new ArgumentNullException(nameof(contextDir)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } // Register Hbs helpers and partial templates HandlebarsHelperService.RegisterHelpers(); DbContextTemplateService.RegisterPartialTemplates(); EntityTypeTemplateService.RegisterPartialTemplates(); var resultingFiles = new ScaffoldedModel(); string generatedCode; if (!(CSharpDbContextGenerator is NullCSharpDbContextGenerator)) { generatedCode = CSharpDbContextGenerator.WriteCode(model, @namespace, contextName, connectionString, options.UseDataAnnotations, options.SuppressConnectionStringWarning); var dbContextFileName = contextName + FileExtension; resultingFiles.ContextFile = new ScaffoldedFile { Path = Path.Combine(contextDir, dbContextFileName), Code = generatedCode }; } if (!(CSharpEntityTypeGenerator is NullCSharpEntityTypeGenerator)) { foreach (var entityType in model.GetEntityTypes()) { generatedCode = CSharpEntityTypeGenerator.WriteCode(entityType, @namespace, options.UseDataAnnotations); var transformedFileName = EntityTypeTransformationService.TransformEntityFileName(entityType.DisplayName()); var entityTypeFileName = transformedFileName + FileExtension; resultingFiles.AdditionalFiles.Add(new ScaffoldedFile { Path = entityTypeFileName, Code = generatedCode }); } } return(resultingFiles); }
public override ScaffoldedModel GenerateModel(IModel model, ModelCodeGenerationOptions options) { if (options.ContextName == null) { throw new ArgumentException( CoreStrings.ArgumentPropertyNull(nameof(options.ContextName), nameof(options)), nameof(options)); } if (options.ConnectionString == null) { throw new ArgumentException( CoreStrings.ArgumentPropertyNull(nameof(options.ConnectionString), nameof(options)), nameof(options)); } var resultingFiles = new ScaffoldedModel(); var contextTemplate = Path.Combine(options.ProjectDir !, TemplatesDirectory, "DbContext.t4"); Check.DebugAssert(_host.Session == null, "Session is not null."); _host.Session = _host.CreateSession(); try { _host.Session.Add("Model", model); _host.Session.Add("Options", options); _host.Session.Add("NamespaceHint", options.ContextNamespace ?? options.ModelNamespace); _host.Session.Add("ProjectDefaultNamespace", options.RootNamespace); var handler = new TextTemplatingCallback(); var generatedCode = ProcessTemplate(contextTemplate, handler); var dbContextFileName = options.ContextName + handler.Extension; resultingFiles.ContextFile = new ScaffoldedFile { Path = options.ContextDir != null ? Path.Combine(options.ContextDir, dbContextFileName) : dbContextFileName, Code = generatedCode }; } finally { _host.Session = null; } var entityTypeTemplate = Path.Combine(options.ProjectDir !, TemplatesDirectory, "EntityType.t4"); if (File.Exists(entityTypeTemplate)) { foreach (var entityType in model.GetEntityTypes()) { // TODO: Should this be handled inside the template? if (CSharpDbContextGenerator.IsManyToManyJoinEntityType(entityType)) { continue; } _host.Session = _host.CreateSession(); try { _host.Session.Add("EntityType", entityType); _host.Session.Add("Options", options); _host.Session.Add("NamespaceHint", options.ModelNamespace); _host.Session.Add("ProjectDefaultNamespace", options.RootNamespace); var handler = new TextTemplatingCallback(); var generatedCode = ProcessTemplate(entityTypeTemplate, handler); if (string.IsNullOrWhiteSpace(generatedCode)) { continue; } var entityTypeFileName = entityType.Name + handler.Extension; resultingFiles.AdditionalFiles.Add( new ScaffoldedFile { Path = entityTypeFileName, Code = generatedCode }); } finally { _host.Session = null; } } } return(resultingFiles); }
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); }
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 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> /// Generates code for a model. /// </summary> /// <param name="model">The model.</param> /// <param name="options">The options to use during generation.</param> /// <returns>The generated model.</returns> public abstract ScaffoldedModel GenerateModel( IModel model, ModelCodeGenerationOptions options);