private void ValidateContextNameInReverseEngineerGenerator(string contextName) { var reverseEngineer = new ServiceCollection() .AddEntityFrameworkDesignTimeServices() .AddSingleton <LoggingDefinitions, TestRelationalLoggingDefinitions>() .AddSingleton <IRelationalTypeMappingSource, TestRelationalTypeMappingSource>() .AddSingleton <IAnnotationCodeGenerator, AnnotationCodeGenerator>() .AddSingleton <IDatabaseModelFactory, FakeDatabaseModelFactory>() .AddSingleton <IProviderConfigurationCodeGenerator, TestProviderCodeGenerator>() .AddSingleton <IScaffoldingModelFactory, FakeScaffoldingModelFactory>() .BuildServiceProvider() .GetRequiredService <IReverseEngineerScaffolder>(); Assert.Equal( DesignStrings.ContextClassNotValidCSharpIdentifier(contextName), Assert.Throws <ArgumentException>( () => reverseEngineer.ScaffoldModel( "connectionstring", new DatabaseModelFactoryOptions( /* tables: */ Enumerable.Empty <string>(), /* schemas: */ Enumerable.Empty <string>()), "FakeNamespace", "FakeNamespace", "FakeNamespace", /* language: */ "", /* contextDir: */ null, contextName, new ModelReverseEngineerOptions(), new ModelCodeGenerationOptions())) .Message); }
/// <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 void ValidateContextNameInReverseEngineerGenerator(string contextName) { var reverseEngineer = new ServiceCollection() .AddEntityFrameworkDesignTimeServices() .AddSingleton <IAnnotationCodeGenerator, FakeAnnotationCodeGenerator>() .AddSingleton <IDatabaseModelFactory, FakeDatabaseModelFactory>() .AddSingleton <IProviderCodeGenerator, TestProviderCodeGenerator>() .AddSingleton <IScaffoldingModelFactory, FakeScaffoldingModelFactory>() .BuildServiceProvider() .GetRequiredService <IReverseEngineerScaffolder>(); Assert.Equal( DesignStrings.ContextClassNotValidCSharpIdentifier(contextName), Assert.Throws <ArgumentException>( () => reverseEngineer.ScaffoldModel( connectionString: "connectionstring", tables: Enumerable.Empty <string>(), schemas: Enumerable.Empty <string>(), @namespace: "FakeNamespace", language: "", contextName: contextName, useDataAnnotations: false, useDatabaseNames: false)) .Message); }
private void ValidateContextNameInReverseEngineerGenerator(string contextName) { var cSharpUtilities = new CSharpUtilities(); var reverseEngineer = new ReverseEngineerScaffolder( new RelationalDatabaseModelFactoryTest.FakeDatabaseModelFactory(), new RelationalDatabaseModelFactoryTest.FakeScaffoldingModelFactory(new TestOperationReporter()), new CSharpScaffoldingGenerator( new InMemoryFileService(), new CSharpDbContextGenerator(new FakeScaffoldingCodeGenerator(), new FakeAnnotationCodeGenerator(), cSharpUtilities), new CSharpEntityTypeGenerator(cSharpUtilities)), cSharpUtilities); Assert.Equal( DesignStrings.ContextClassNotValidCSharpIdentifier(contextName), Assert.Throws <ArgumentException>( () => reverseEngineer.Generate( connectionString: "connectionstring", tables: Enumerable.Empty <string>(), schemas: Enumerable.Empty <string>(), projectPath: "FakeProjectPath", outputPath: null, rootNamespace: "FakeNamespace", contextName: contextName, useDataAnnotations: false, overwriteFiles: false, useDatabaseNames: false)) .Message); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual void CheckValidity() { if (string.IsNullOrEmpty(ConnectionString)) { throw new ArgumentException(DesignStrings.ConnectionStringRequired); } if (string.IsNullOrEmpty(ProjectPath)) { throw new ArgumentException(DesignStrings.ProjectPathRequired); } if (!string.IsNullOrWhiteSpace(ContextClassName) && (!CSharpUtilities.Instance.IsValidIdentifier(ContextClassName) || CSharpUtilities.Instance.IsCSharpKeyword(ContextClassName))) { throw new ArgumentException( DesignStrings.ContextClassNotValidCSharpIdentifier(ContextClassName)); } if (string.IsNullOrEmpty(ProjectRootNamespace)) { throw new ArgumentException(DesignStrings.RootNamespaceRequired); } }
/// <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)); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual ScaffoldedModel ScaffoldModel( string connectionString, IEnumerable <string> tables, IEnumerable <string> schemas, string @namespace, string language, string contextDir, string contextName, bool useDataAnnotations, bool useDatabaseNames) { Check.NotEmpty(connectionString, nameof(connectionString)); Check.NotNull(tables, nameof(tables)); Check.NotNull(schemas, nameof(schemas)); Check.NotEmpty(@namespace, nameof(@namespace)); Check.NotNull(language, nameof(language)); if (!string.IsNullOrWhiteSpace(contextName) && (!_cSharpUtilities.IsValidIdentifier(contextName) || _cSharpUtilities.IsCSharpKeyword(contextName))) { throw new ArgumentException( DesignStrings.ContextClassNotValidCSharpIdentifier(contextName)); } var databaseModel = _databaseModelFactory.Create(connectionString, tables, schemas); var model = _factory.Create(databaseModel, useDatabaseNames); if (model == null) { throw new InvalidOperationException( DesignStrings.ProviderReturnedNullModel( _factory.GetType().ShortDisplayName())); } if (string.IsNullOrEmpty(contextName)) { contextName = DefaultDbContextName; var annotatedName = model.Scaffolding().DatabaseName; if (!string.IsNullOrEmpty(annotatedName)) { contextName = _cSharpUtilities.GenerateCSharpIdentifier( annotatedName + DbContextSuffix, existingIdentifiers: null, singularizePluralizer: null); } } var codeGenerator = ModelCodeGeneratorSelector.Select(language); return(codeGenerator.GenerateModel(model, @namespace, contextDir ?? string.Empty, contextName, connectionString, useDataAnnotations)); }
public void Throws_exceptions_for_incorrect_configuration() { var configuration = new ReverseEngineeringConfiguration { ConnectionString = null, ProjectPath = null, OutputPath = null }; Assert.Equal(DesignStrings.ConnectionStringRequired, Assert.Throws <ArgumentException>( () => configuration.CheckValidity()).Message); configuration.ConnectionString = "NonEmptyConnectionString"; Assert.Equal(DesignStrings.ProjectPathRequired, Assert.Throws <ArgumentException>( () => configuration.CheckValidity()).Message); configuration.ProjectPath = "NonEmptyProjectPath"; Assert.Equal(DesignStrings.RootNamespaceRequired, Assert.Throws <ArgumentException>( () => configuration.CheckValidity()).Message); configuration.ContextClassName = @"Invalid!CSharp*Class&Name"; Assert.Equal(DesignStrings.ContextClassNotValidCSharpIdentifier(@"Invalid!CSharp*Class&Name"), Assert.Throws <ArgumentException>( () => configuration.CheckValidity()).Message); configuration.ContextClassName = "1CSharpClassNameCannotStartWithNumber"; Assert.Equal(DesignStrings.ContextClassNotValidCSharpIdentifier("1CSharpClassNameCannotStartWithNumber"), Assert.Throws <ArgumentException>( () => configuration.CheckValidity()).Message); configuration.ContextClassName = "volatile"; // cannot be C# keyword Assert.Equal(DesignStrings.ContextClassNotValidCSharpIdentifier("volatile"), Assert.Throws <ArgumentException>( () => configuration.CheckValidity()).Message); configuration.ContextClassName = "GoodClassName"; configuration.OutputPath = @"\AnAbsolutePath"; Assert.Equal(DesignStrings.RootNamespaceRequired, Assert.Throws <ArgumentException>( () => configuration.CheckValidity()).Message); configuration.OutputPath = @"A\Relative\Path"; Assert.Equal(DesignStrings.RootNamespaceRequired, Assert.Throws <ArgumentException>( () => configuration.CheckValidity()).Message); }
private void ValidateContextNameInReverseEngineerGenerator(string contextName) { var assembly = typeof(ReverseEngineeringConfigurationTests).Assembly; var reverseEngineer = new DesignTimeServicesBuilder(assembly, assembly, new TestOperationReporter(), new string[0]) .Build("Microsoft.EntityFrameworkCore.SqlServer") .GetRequiredService <IReverseEngineerScaffolder>(); Assert.Equal( DesignStrings.ContextClassNotValidCSharpIdentifier(contextName), Assert.Throws <ArgumentException>( () => reverseEngineer.ScaffoldModel( "connectionstring", new DatabaseModelFactoryOptions(), new ModelReverseEngineerOptions(), new ModelCodeGenerationOptions { ModelNamespace = "FakeNamespace", ContextName = contextName })) .Message); }
public void ValidateContextNameInReverseEngineerGenerator(string contextName) { var reverseEngineer = new ServiceCollection() .AddEntityFrameworkDesignTimeServices() .AddSingleton <LoggingDefinitions, TestRelationalLoggingDefinitions>() .AddSingleton <IRelationalTypeMappingSource, TestRelationalTypeMappingSource>() .AddSingleton <IAnnotationCodeGenerator, AnnotationCodeGenerator>() .AddSingleton <IDatabaseModelFactory, FakeDatabaseModelFactory>() .AddSingleton <IProviderConfigurationCodeGenerator, TestProviderCodeGenerator>() .AddSingleton <IScaffoldingModelFactory, FakeScaffoldingModelFactory>() .AddSingleton <IModelCodeGenerator, HbsCSharpModelGenerator>() .AddSingleton <ICSharpDbContextGenerator, HbsCSharpDbContextGenerator>() .AddSingleton <ICSharpEntityTypeGenerator, HbsCSharpEntityTypeGenerator>() .AddSingleton <IDbContextTemplateService, HbsDbContextTemplateService>() .AddSingleton <ITemplateFileService, InMemoryTemplateFileService>() .AddSingleton <ITemplateLanguageService, FakeCSharpTemplateLanguageService>() .AddSingleton <IEntityTypeTemplateService, HbsEntityTypeTemplateService>() .AddSingleton <IReverseEngineerScaffolder, HbsReverseEngineerScaffolder>() .AddSingleton <IEntityTypeTransformationService, HbsEntityTypeTransformationService>() .AddSingleton <IContextTransformationService, HbsContextTransformationService>() .AddSingleton <IHbsHelperService>(provider => new HbsHelperService( new Dictionary <string, Action <TextWriter, Dictionary <string, object>, object[]> > { { Constants.SpacesHelper, HandlebarsHelpers.SpacesHelper } })) .AddSingleton <IHbsBlockHelperService>(provider => new HbsBlockHelperService(new Dictionary <string, Action <TextWriter, HelperOptions, Dictionary <string, object>, object[]> >())) .BuildServiceProvider() .GetRequiredService <IReverseEngineerScaffolder>(); Assert.Equal(DesignStrings.ContextClassNotValidCSharpIdentifier(contextName), Assert.Throws <ArgumentException>( () => reverseEngineer.ScaffoldModel( connectionString: "connectionstring", databaseOptions: new DatabaseModelFactoryOptions(), modelOptions: new ModelReverseEngineerOptions(), codeOptions: new ModelCodeGenerationOptions() { ModelNamespace = "FakeNamespace", ContextName = contextName, })) .Message); }
private void ValidateContextNameInReverseEngineerGenerator(string contextName) { var cSharpUtilities = new CSharpUtilities(); var reverseEngineer = new ReverseEngineerScaffolder( new FakeDatabaseModelFactory(), new FakeScaffoldingModelFactory(new TestOperationReporter()), new ScaffoldingCodeGeneratorSelector( new[] { new CSharpScaffoldingGenerator( new CSharpDbContextGenerator( #pragma warning disable CS0618 // Type or member is obsolete Enumerable.Empty <IScaffoldingProviderCodeGenerator>(), #pragma warning restore CS0618 // Type or member is obsolete new[] { new TestProviderCodeGenerator() }, new FakeAnnotationCodeGenerator(), cSharpUtilities), new CSharpEntityTypeGenerator(cSharpUtilities)) }), cSharpUtilities); Assert.Equal( DesignStrings.ContextClassNotValidCSharpIdentifier(contextName), Assert.Throws <ArgumentException>( () => reverseEngineer.Generate( connectionString: "connectionstring", tables: Enumerable.Empty <string>(), schemas: Enumerable.Empty <string>(), projectPath: "FakeProjectPath", outputPath: null, rootNamespace: "FakeNamespace", language: "", contextName: contextName, useDataAnnotations: false, useDatabaseNames: false)) .Message); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual ReverseEngineerFiles Generate( string connectionString, IEnumerable <string> tables, IEnumerable <string> schemas, string projectPath, string outputPath, string rootNamespace, string contextName, bool useDataAnnotations, bool overwriteFiles, bool useDatabaseNames) { if (connectionString == null) { throw new ArgumentNullException(nameof(connectionString)); } if (tables == null) { throw new ArgumentNullException(nameof(tables)); } if (schemas == null) { throw new ArgumentNullException(nameof(schemas)); } if (projectPath == null) { throw new ArgumentNullException(nameof(projectPath)); } if (rootNamespace == null) { throw new ArgumentNullException(nameof(rootNamespace)); } if (!string.IsNullOrWhiteSpace(contextName) && (!_cSharpUtilities.IsValidIdentifier(contextName) || _cSharpUtilities.IsCSharpKeyword(contextName))) { throw new ArgumentException( DesignStrings.ContextClassNotValidCSharpIdentifier(contextName)); } var databaseModel = _databaseModelFactory.Create(connectionString, tables, schemas); //var model = _factory.Create(connectionString, tables, schemas, useDatabaseNames); var model = _factory.Create(databaseModel, useDatabaseNames); if (model == null) { throw new InvalidOperationException( DesignStrings.ProviderReturnedNullModel( _factory.GetType().ShortDisplayName())); } outputPath = string.IsNullOrWhiteSpace(outputPath) ? null : outputPath; var subNamespace = SubnamespaceFromOutputPath(projectPath, outputPath); var @namespace = rootNamespace; if (!string.IsNullOrEmpty(subNamespace)) { @namespace += "." + subNamespace; } if (string.IsNullOrEmpty(contextName)) { contextName = DefaultDbContextName; var annotatedName = model.Scaffolding().DatabaseName; if (!string.IsNullOrEmpty(annotatedName)) { contextName = _cSharpUtilities.GenerateCSharpIdentifier( annotatedName + DbContextSuffix, existingIdentifiers: null, singularizePluralizer: null); } } CheckOutputFiles(outputPath ?? projectPath, contextName, model, overwriteFiles); return(ScaffoldingCodeGenerator.WriteCode(model, outputPath ?? projectPath, @namespace, contextName, connectionString, useDataAnnotations)); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual ReverseEngineerFiles Generate( string connectionString, IEnumerable <string> tables, IEnumerable <string> schemas, string projectPath, string outputPath, string rootNamespace, string contextName, bool useDataAnnotations, bool overwriteFiles, bool useDatabaseNames) { Check.NotEmpty(connectionString, nameof(connectionString)); Check.NotNull(tables, nameof(tables)); Check.NotNull(schemas, nameof(schemas)); Check.NotEmpty(projectPath, nameof(projectPath)); Check.NotEmpty(rootNamespace, nameof(rootNamespace)); if (!string.IsNullOrWhiteSpace(contextName) && (!_cSharpUtilities.IsValidIdentifier(contextName) || _cSharpUtilities.IsCSharpKeyword(contextName))) { throw new ArgumentException( DesignStrings.ContextClassNotValidCSharpIdentifier(contextName)); } var databaseModel = _databaseModelFactory.Create(connectionString, tables, schemas); var model = _factory.Create(databaseModel, useDatabaseNames); if (model == null) { throw new InvalidOperationException( DesignStrings.ProviderReturnedNullModel( _factory.GetType().ShortDisplayName())); } projectPath = projectPath.TrimEnd(_directorySeparatorChars); var fullProjectPath = Path.GetFullPath(projectPath); var fullOutputPath = string.IsNullOrEmpty(outputPath) ? fullProjectPath : Path.GetFullPath(Path.Combine(projectPath, outputPath)); var @namespace = rootNamespace; if (!string.Equals(fullOutputPath, fullProjectPath) && fullOutputPath.StartsWith(fullProjectPath, StringComparison.Ordinal)) { var relativeOutputPath = fullOutputPath.Substring(fullProjectPath.Length + 1); @namespace += "." + string.Join( ".", relativeOutputPath .Split(_directorySeparatorChars, StringSplitOptions.RemoveEmptyEntries) .Select( p => _cSharpUtilities.GenerateCSharpIdentifier( p, existingIdentifiers: null, singularizePluralizer: null))); } if (string.IsNullOrEmpty(contextName)) { contextName = DefaultDbContextName; var annotatedName = model.Scaffolding().DatabaseName; if (!string.IsNullOrEmpty(annotatedName)) { contextName = _cSharpUtilities.GenerateCSharpIdentifier( annotatedName + DbContextSuffix, existingIdentifiers: null, singularizePluralizer: null); } } CheckOutputFiles(fullOutputPath, contextName, model, overwriteFiles); return(ScaffoldingCodeGenerator.WriteCode(model, fullOutputPath, @namespace, contextName, connectionString, useDataAnnotations)); }