コード例 #1
0
        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);
        }
コード例 #2
0
        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));
        }
コード例 #3
0
ファイル: DatabaseOperations.cs プロジェクト: donhuvy/efcore
    /// <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));
    }
コード例 #4
0
        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);
            }
        }
コード例 #5
0
        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);
            }
        }
コード例 #6
0
        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);
            }
        }
コード例 #7
0
    /// <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));
    }
コード例 #8
0
    /// <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..];
コード例 #9
0
        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
            });
        }
コード例 #10
0
            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.");
                }
            }
コード例 #11
0
 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);
     }
 }
コード例 #12
0
        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;
        }