public static ScaffoldedModel ScaffoldContext( [NotNull] string provider, [NotNull] string connectionString, [CanBeNull] string outputDir, [CanBeNull] string outputContextDir, [CanBeNull] string dbContextClassName, [NotNull] IEnumerable <string> schemas, [NotNull] IEnumerable <string> tables, bool useDataAnnotations, bool overwriteFiles, bool useDatabaseNames) { var unwrappedReportHandler = ForwardingProxy.Unwrap <IOperationReportHandler>(new OperationReportHandler()); var reporter = new OperationReporter(unwrappedReportHandler); var _servicesBuilder = new DesignTimeServicesBuilder(Assembly.GetExecutingAssembly(), reporter, Array.Empty <string>()); var services = _servicesBuilder.Build(provider); var scaffolder = services.GetRequiredService <IReverseEngineerScaffolder>(); var @namespace = "DiplomWork"; var scaffoldedModel = scaffolder.ScaffoldModel( connectionString, tables, schemas, @namespace, null, MakeDirRelative(outputDir, outputContextDir), dbContextClassName, new ModelReverseEngineerOptions { UseDatabaseNames = useDatabaseNames }, new ModelCodeGenerationOptions { UseDataAnnotations = useDataAnnotations }); return(scaffoldedModel); }
public virtual Task <ReverseEngineerFiles> ReverseEngineerAsync( [NotNull] string provider, [NotNull] string connectionString, [CanBeNull] string outputDir, [CanBeNull] string dbContextClassName, [CanBeNull] string tableFilters, bool useFluentApiOnly, CancellationToken cancellationToken = default(CancellationToken)) { Check.NotEmpty(provider, nameof(provider)); Check.NotEmpty(connectionString, nameof(connectionString)); var services = _servicesBuilder.Build(provider); var loggerFactory = services.GetRequiredService <ILoggerFactory>(); loggerFactory.AddProvider(_loggerProvider); var generator = services.GetRequiredService <ReverseEngineeringGenerator>(); var tableSelectionSet = TableSelectionSetBuilder.BuildFromString(tableFilters); var configuration = new ReverseEngineeringConfiguration { ConnectionString = connectionString, ContextClassName = dbContextClassName, ProjectPath = _projectDir, ProjectRootNamespace = _rootNamespace, OutputPath = outputDir, TableSelectionSet = tableSelectionSet, UseFluentApiOnly = useFluentApiOnly }; return(generator.GenerateAsync(configuration, cancellationToken)); }
/// <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 SavedModelFiles ScaffoldContext( string provider, string connectionString, string?outputDir, string?outputContextDir, string?dbContextClassName, IEnumerable <string> schemas, IEnumerable <string> tables, string?modelNamespace, string?contextNamespace, bool useDataAnnotations, bool overwriteFiles, bool useDatabaseNames, bool suppressOnConfiguring, bool noPluralize) { outputDir = outputDir != null ? Path.GetFullPath(Path.Combine(_projectDir, outputDir)) : _projectDir; outputContextDir = outputContextDir != null ? Path.GetFullPath(Path.Combine(_projectDir, outputContextDir)) : outputDir; var services = _servicesBuilder.Build(provider); using var scope = services.CreateScope(); var scaffolder = scope.ServiceProvider.GetRequiredService <IReverseEngineerScaffolder>(); var finalModelNamespace = modelNamespace ?? GetNamespaceFromOutputPath(outputDir); var finalContextNamespace = contextNamespace ?? modelNamespace ?? GetNamespaceFromOutputPath(outputContextDir); var scaffoldedModel = scaffolder.ScaffoldModel( connectionString, new DatabaseModelFactoryOptions(tables, schemas), new ModelReverseEngineerOptions { UseDatabaseNames = useDatabaseNames, NoPluralize = noPluralize }, new ModelCodeGenerationOptions { UseDataAnnotations = useDataAnnotations, RootNamespace = _rootNamespace, ModelNamespace = finalModelNamespace, ContextNamespace = finalContextNamespace, Language = _language, UseNullableReferenceTypes = _nullable, ContextDir = MakeDirRelative(outputDir, outputContextDir), ContextName = dbContextClassName, SuppressOnConfiguring = suppressOnConfiguring, ProjectDir = _projectDir }); return(scaffolder.Save( scaffoldedModel, outputDir, overwriteFiles)); }
public virtual MigrationFiles AddMigration( [NotNull] string name, [CanBeNull] string contextType) { Check.NotEmpty(name, nameof(name)); using (var context = _contextOperations.CreateContext(contextType)) { var services = _servicesBuilder.Build(context); EnsureServices(services); var scaffolder = services.GetRequiredService <MigrationsScaffolder>(); var migration = scaffolder.ScaffoldMigration(name, _rootNamespace); var files = scaffolder.Save(_projectDir, migration); return(files); } }
public virtual MigrationFiles AddMigration( [NotNull] string name, [CanBeNull] string outputDir, [CanBeNull] string contextType) { Check.NotEmpty(name, nameof(name)); outputDir = string.IsNullOrWhiteSpace(outputDir) ? null : outputDir; var subNamespace = SubnamespaceFromOutputPath(outputDir); using (var context = _contextOperations.CreateContext(contextType)) { var services = _servicesBuilder.Build(context); EnsureServices(services); var scaffolder = services.GetRequiredService <MigrationsScaffolder>(); var migration = scaffolder.ScaffoldMigration(name, _rootNamespace, subNamespace); var files = scaffolder.Save(_projectDir, migration, outputDir); return(files); } }
public virtual MigrationFiles AddMigration( [NotNull] string name, [CanBeNull] string outputDir, [CanBeNull] string contextType) { Check.NotEmpty(name, nameof(name)); var subNamespace = outputDir != null ? string.Join(".", outputDir.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)) : null; using (var context = _contextOperations.CreateContext(contextType)) { var services = _servicesBuilder.Build(context); EnsureServices(services); var scaffolder = services.GetRequiredService <MigrationsScaffolder>(); var migration = scaffolder.ScaffoldMigration(name, _rootNamespace, subNamespace); var files = scaffolder.Save(_projectDir, migration); return(files); } }
/// <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 MigrationFiles AddMigration( string name, string?outputDir, string?contextType, string? @namespace) { if (outputDir != null) { outputDir = Path.GetFullPath(Path.Combine(_projectDir, outputDir)); } var subNamespace = SubnamespaceFromOutputPath(outputDir); using var context = _contextOperations.CreateContext(contextType); var contextClassName = context.GetType().Name; if (string.Equals(name, contextClassName, StringComparison.Ordinal)) { throw new OperationException( DesignStrings.ConflictingContextAndMigrationName(name)); } var services = _servicesBuilder.Build(context); EnsureServices(services); EnsureMigrationsAssembly(services); using var scope = services.CreateScope(); var scaffolder = scope.ServiceProvider.GetRequiredService <IMigrationsScaffolder>(); var migration = string.IsNullOrEmpty(@namespace) // TODO: Honor _nullable (issue #18950) ? scaffolder.ScaffoldMigration(name, _rootNamespace ?? string.Empty, subNamespace, _language) : scaffolder.ScaffoldMigration(name, null, @namespace, _language); return(scaffolder.Save(_projectDir, migration, outputDir)); }
/// <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 void Optimize(string?outputDir, string?modelNamespace, string?contextTypeName) { using var context = CreateContext(contextTypeName); var contextType = context.GetType(); var services = _servicesBuilder.Build(context); var scaffolder = services.GetRequiredService <ICompiledModelScaffolder>(); if (outputDir == null) { var contextSubNamespace = contextType.Namespace ?? ""; if (!string.IsNullOrEmpty(_rootNamespace) && contextSubNamespace.StartsWith(_rootNamespace, StringComparison.Ordinal)) { contextSubNamespace = contextSubNamespace[_rootNamespace.Length..];
public virtual DirectiveFiles GenerateRuntimeDirectives() { var generator = new DirectiveGenerator(); var members = new List <MemberInfo>(); foreach (var contextType in FindContextTypes()) { var contextTypeName = contextType.Key.GetTypeInfo().FullName; using (var context = CreateContext(contextType.Value)) { var services = _servicesBuilder.Build(context); var discoverer = services.GetRequiredService <RuntimeTypeDiscoverer>(); _logger.Value.LogDebug(CommandsStrings.BeginRuntimeTypeDiscovery(contextTypeName)); var start = members.Count; var assemblies = new[] { typeof(EntityType).GetTypeInfo().Assembly, typeof(RelationalDatabase).GetTypeInfo().Assembly, context.GetInfrastructure() .GetRequiredService <IDbContextServices>() .DatabaseProviderServices .GetType() .GetTypeInfo() .Assembly }; members.AddRange(discoverer.Discover(assemblies)); _logger.Value.LogDebug(CommandsStrings.EndRuntimeTypeDiscovery(members.Count - start, contextTypeName)); } } var xml = generator.GenerateXml(members); var filename = Path.Combine(_projectDir, "Properties", "Microsoft.EntityFrameworkCore.g.rd.xml"); Directory.CreateDirectory(Path.GetDirectoryName(filename)); _logger.Value.LogInformation(CommandsStrings.WritingDirectives(filename)); File.WriteAllText(filename, xml); return(new DirectiveFiles { GeneratedFile = filename }); }
public void ModelChangesAreNotPending() { var servicesBuilder = new DesignTimeServicesBuilder(Assembly.GetExecutingAssembly(), Mock.Of <IOperationReporter>()); var services = servicesBuilder.Build(db); var dependencies = services.GetService <MigrationsScaffolderDependencies>(); var modelSnapshot = dependencies.MigrationsAssembly.ModelSnapshot; Assert.NotNull(modelSnapshot); var lastModel = dependencies.SnapshotModelProcessor.Process(modelSnapshot.Model); var upOperations = dependencies.MigrationsModelDiffer.GetDifferences(lastModel, dependencies.Model); if (upOperations.Any()) { throw new XunitException("There are pending model changes."); } }
public virtual MigrationFiles Add([NotNull] string name, string @namespace = null) { // TODO: Try to find existing migration and use that namespace (maybe?) @namespace = @namespace ?? Path.GetDirectoryName(ProjectPath); using (var context = ResolveDbContext()) { var services = _servicesBuilder.Build(context); var requiredService = services.GetRequiredService <MigrationsScaffolder>(); var migration = requiredService.ScaffoldMigration(name, @namespace, ""); var files = requiredService.Save(ProjectPath, migration, null); Console.WriteLine($"Migration \"{name}\" successfully scaffolded".Bold().Black()); Console.WriteLine(); WrieOutFile("Metadata", files.MetadataFile); WrieOutFile("Migration", files.MigrationFile); WrieOutFile("Snapshot", files.SnapshotFile); return(files); } }
public EFCoreAutoMigrator(DbContext _dbContext, ILogger _logger) { dbMigratorProps = new DBMigratorProps() { dbContext = _dbContext, logger = _logger, dbMigratorTableMetatdata = new DefaultMigrationMetadata(), migrationProviderFactory = new MigrationProviderFactory(), allowDestructive = false, snapshotHistoryLimit = -1 }; var migrationAssembly = _dbContext.GetService <IMigrationsAssembly>(); DesignTimeServicesBuilder builder = new DesignTimeServicesBuilder(migrationAssembly.Assembly, Assembly.GetEntryAssembly(), this, null); var dbServices = builder.Build(_dbContext); var dependencies = dbServices.GetRequiredService <MigrationsScaffolderDependencies>(); var migrationName = dependencies.MigrationsIdGenerator.GenerateId(Utilities.DalConsts.MIGRATION_NAME_PREFIX); dbMigratorProps.dbServices = dbServices; dbMigratorProps.migrationName = migrationName; }