예제 #1
0
        public void AddMigration(string name, string outputDir, bool ignoreChanges)
        {
            var config        = FindDbMigrationsConfiguration();
            var migrationsDir = GetMigrationsDir(outputDir ?? config.MigrationsDirectory);

            Directory.CreateDirectory(migrationsDir);

            // Scaffold migration.
            var scaffolder = new MigrationScaffolder(config);
            var migration  = scaffolder.Scaffold(name, ignoreChanges);

            // Write the user code file.
            File.WriteAllText(Combine(migrationsDir, migration.MigrationId + ".cs"), migration.UserCode);

            // Write needed resource values directly inside the designer code file.
            // It'll be a pain to ask the users to embed the resources from project.json.
            var targetValue  = migration.Resources["Target"];
            var designerCode = migration.DesignerCode
                               .Replace("Resources.GetString(\"Target\")", $"\"{targetValue}\"");

            if (migration.Resources.TryGetValue("Source", out object sourceObject))
            {
                var sourceValue = sourceObject as string;
                designerCode = designerCode
                               .Replace("Resources.GetString(\"Source\")", $"\"{sourceValue}\"");
            }

            // Write the designer code file.
            File.WriteAllText(Path.Combine(migrationsDir, migration.MigrationId + ".Designer.cs"), designerCode);
        }
        public void Add(string title)
        {
            var scaffolder = new MigrationScaffolder(_config);

            var migration = scaffolder.Scaffold(title);

            //Because monodevelop/xamarin doesn't support resxfilecodegenerator, we can't user resx files properly
            //Another issue is lack of power shell support which force us to generate all cs/resx files manually and add them to
            //projet, what is why we are going to put all migration data to one file using ugly hacks
            //Code might stop working on future versions of Entity framework.

            //Add Migration Namespace
            migration.UserCode = "using System.Data.Entity.Migrations.Infrastructure;\n\n" + migration.UserCode;

            //Add IMigrationMetadata interface
            migration.UserCode = migration.UserCode.Replace("DbMigration", "DbMigration, IMigrationMetadata");

            //Insert IMigrationMetadate implementation
            migration.UserCode = migration.UserCode.Replace("public override void Up()",
                                                            string.Format("\tstring IMigrationMetadata.Id {{\n\t\t\t" +
                                                                          "get {{ return \"{0}\"; }}\n\t\t" +
                                                                          "}}\n\n\t\t" +
                                                                          "string IMigrationMetadata.Source {{\n\t\t\t" +
                                                                          "get {{ return null; }}\n\t\t" +
                                                                          "}}\n\n\n\t\t" +
                                                                          "string IMigrationMetadata.Target {{\n\t\t\t" +
                                                                          "get {{ return \"{1}\"; }}\n\t\t}}" +
                                                                          "\n\n\tpublic override void Up()", migration.MigrationId, migration.Resources ["Target"]));

            File.WriteAllText(Path.Combine(_migrationFolder, migration.MigrationId + ".cs"), migration.UserCode);
        }
예제 #3
0
        public void AddMigration(string name, string outputDir, bool ignoreChanges)
        {
            var config        = FindDbMigrationsConfiguration();
            var migrationsDir = GetMigrationsDir(outputDir ?? config.MigrationsDirectory);

            Directory.CreateDirectory(migrationsDir);

            // Scaffold migration.
            var scaffolder = new MigrationScaffolder(config);
            var migration  = scaffolder.Scaffold(name, ignoreChanges);

            // Write the user code file.
            File.WriteAllText(Combine(migrationsDir, migration.MigrationId + ".cs"), migration.UserCode);

            var className    = GetClassNameFromDesignerFile(migration.DesignerCode);
            var ns           = $"{_rootNamespace}.{GetMigrationsNamespaceFromPath(outputDir)}";
            var designerCode = _resourcesTypeRegex.Replace(
                migration.DesignerCode,
                $"\"{ns}.{migration.MigrationId}\", typeof({className}).Assembly");

            // Write the designer code file.
            File.WriteAllText(Path.Combine(migrationsDir, migration.MigrationId + ".Designer.cs"), designerCode);

            // Write resources file.
            var resourcesPath = Combine(migrationsDir, migration.MigrationId + ".resx");

            WriteResources(resourcesPath, migration.Resources);
        }
예제 #4
0
        public void AddMigration(string name, string outputDir, bool ignoreChanges)
        {
            var migrationsDir = GetMigrationsDir(outputDir);

            Directory.CreateDirectory(migrationsDir);
            var config = FindDbMigrationsConfiguration();

            // Scaffold migration.
            var scaffolder = new MigrationScaffolder(config);
            var migration  = scaffolder.Scaffold(name, ignoreChanges);

            // Write the user code file.
            File.WriteAllText(Combine(migrationsDir, migration.MigrationId + ".cs"), migration.UserCode);

            // Write needed resource values directly inside the designer code file.
            // Apparently, aspnet and resource files don't play well (or more specifically,
            // the way ef6 migration generator is interacting with the resources system)
            var targetValue  = migration.Resources["Target"];
            var designerCode = migration.DesignerCode
                               .Replace("Resources.GetString(\"Target\")", $"\"{targetValue}\"")
                               .Replace("private readonly ResourceManager Resources = new ResourceManager(typeof(InitialCreate));", "");

            // Write the designer code file.
            File.WriteAllText(Path.Combine(migrationsDir, migration.MigrationId + ".Designer.cs"), designerCode);
        }
예제 #5
0
        /*
         * public static string GetAllMigration()
         * {
         *
         *
         *  var config = new DbMigrationsConfiguration<SampleDBContext> { AutomaticMigrationsEnabled = true };
         *
         *  var migrator = new DbMigrator(config);
         *
         *  //Get code migration//
         *  var scaffolder = new MigrationScaffolder(migrator.Configuration);
         *
         *  ScaffoldedMigration migration = scaffolder.Scaffold("codeMigration");
         *
         *  var migrationFile = System.IO.Path.Combine(rootPath, migration.Directory, migration.MigrationId);
         *
         *  var userCodeFile = migrationFile + ".cs";
         *
         *  File.WriteAllText(userCodeFile, migration.UserCode);
         *
         *  //Get Db script//
         *  var scriptor = new MigratorScriptingDecorator(migrator);
         *
         *  string script = scriptor.ScriptUpdate(sourceMigration: null, targetMigration: null);
         *
         *  var SqlScriptFile = migrationFile + ".sql";
         *
         *  File.WriteAllText(SqlScriptFile, script);
         *
         *  //Get Edmx Document//
         *
         *  var _currenModelProp = migrator.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance).Single(m => m.Name == "_currentModel");
         *
         *  var _currenModelValueXDOC = (XDocument)_currenModelProp.GetValue(migrator);
         *
         *  var edmxFile = migrationFile + ".xml";
         *
         *
         *  File.WriteAllText(edmxFile, _currenModelValueXDOC.ToString());
         *
         *  return script;
         * }
         */

        static void gettypfromassebmly()
        {
            var assemblyPath = @"C:\Users\rajneesh.kumar\source\repos\EF6-Code-First-Demo-master\EF6CodeFirstDemo\bin\Debug";

            var assemblyName = string.Format(@"{0}\{1}.{2}", assemblyPath, "EF6ClassLibraryCodeFirst", "dll");

            var assembly = Assembly.LoadFrom(assemblyName);

            var type = assembly.GetType("EF6ClassLibraryCodeFirst.SampleDBContext");

            Type genericClass = typeof(DbMigrationsConfiguration <>);

            //MakeGenericType is badly named
            Type constructedClass = genericClass.MakeGenericType(type);

            object created = Activator.CreateInstance(constructedClass);

            ////////////////////////////////////////////////////////////////////
            ///////////////////////////////////////////////////////////////////


            var config = (DbMigrationsConfiguration)created;

            config.AutomaticMigrationsEnabled = true;

            var migrator = new DbMigrator(config);

            //Get code migration//
            var scaffolder = new MigrationScaffolder(migrator.Configuration);

            ScaffoldedMigration migration = scaffolder.Scaffold("codeMigration");

            var migrationFile = System.IO.Path.Combine(rootPath, migration.Directory, migration.MigrationId);

            var userCodeFile = migrationFile + ".cs";

            File.WriteAllText(userCodeFile, migration.UserCode);

            //Get Db script//
            var scriptor = new MigratorScriptingDecorator(migrator);

            string script = scriptor.ScriptUpdate(sourceMigration: null, targetMigration: null);

            var SqlScriptFile = migrationFile + ".sql";

            File.WriteAllText(SqlScriptFile, script);

            //Get Edmx Document//
            var _currenModelProp = migrator.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance).Single(m => m.Name == "_currentModel");

            var _currenModelValueXDOC = (XDocument)_currenModelProp.GetValue(migrator);

            var edmxFile = migrationFile + ".xml";

            File.WriteAllText(edmxFile, _currenModelValueXDOC.ToString());
        }
예제 #6
0
        public static void Main(string[] args)
        {
            var scaffolder = new MigrationScaffolder(new Configuration());
            var migration  = scaffolder.Scaffold("migration1");



            var migrator = new DbMigrator(new Configuration());

            using (var context = new CustomMigrationsDbContext()) {
            }
        }
예제 #7
0
        public void NoPendingMigrations()
        {
            var currentTimestamp = DateTimeOffset.UtcNow.ToString("yyyyMMddHHmmssFFFFFFF");

            _dbName = $"PendingMigrationsTest{currentTimestamp}Validation";
            var connectionString = $@"Data Source=(localdb)\mssqllocaldb; Initial Catalog={_dbName}; Integrated Security=True; MultipleActiveResultSets=True";

            var migrationsConfiguration = new ValidationMigrationsConfiguration
            {
                TargetDatabase = new DbConnectionInfo(connectionString, "System.Data.SqlClient"),
            };

            var dbMigrator = new DbMigrator(migrationsConfiguration);
            var migrations = dbMigrator.GetLocalMigrations();

            dbMigrator.Update(migrations.Last());

            var migrationScaffolder = new MigrationScaffolder(dbMigrator.Configuration);

            var migrationName = $"TestMigration{currentTimestamp}";
            var result        = migrationScaffolder.Scaffold(migrationName);

            _output.WriteLine("Migration content:");
            _output.WriteLine(new string('-', 60));
            _output.WriteLine(result.UserCode);
            _output.WriteLine(new string('-', 60));

            Assert.Equal(
                $@"namespace {dbMigrator.Configuration.MigrationsNamespace}
{{
    using System;
    using System.Data.Entity.Migrations;
    
    public partial class {migrationName} : DbMigration
    {{
        public override void Up()
        {{
        }}
        
        public override void Down()
        {{
        }}
    }}
}}
", result.UserCode);
        }
예제 #8
0
파일: Program.cs 프로젝트: Jonkins/Pokefans
        static void addMigration(string[] args)
        {
            var config     = new Configuration();
            var scaffolder = new MigrationScaffolder(config);
            var migration  = scaffolder.Scaffold(args[1]);

            File.WriteAllText(Path.Combine(args[2], migration.MigrationId + ".cs"), migration.UserCode);

            File.WriteAllText(Path.Combine(args[2], migration.MigrationId + ".Designer.cs"), migration.DesignerCode);

            using (var writer = new ResXResourceWriter(Path.Combine(args[2], migration.MigrationId + ".resx")))
            {
                foreach (var resource in migration.Resources)
                {
                    writer.AddResource(resource.Key, resource.Value);
                }
            }
        }
예제 #9
0
        public void AddMigrations(int i)
        {
            var config     = new DataMigrations();
            var scaffolder = new MigrationScaffolder(config);
            var migration  = scaffolder.Scaffold("Migration" + i);

            File.WriteAllText("Migrations/" + migration.MigrationId + ".cs", migration.UserCode);

            File.WriteAllText("Migrations/" + migration.MigrationId + ".Designer.cs", migration.DesignerCode);

            using (var writer = new ResXResourceWriter("Migrations/" + migration.MigrationId + ".resx"))
            {
                foreach (var resource in migration.Resources)
                {
                    writer.AddResource(resource.Key, resource.Value);
                }
            }
        }
예제 #10
0
        public void MigrationScaffolderDetectsRequiredChanges(ObjectRepository repository, IObjectRepositoryContainer <ObjectRepository> container, IFixture fixture, IServiceProvider serviceProvider, Signature signature, string message)
        {
            // Arrange
            repository = container.AddRepository(repository, signature, message);
            var updated = repository.With(c => c.Add(repository, r => r.Migrations, fixture.Create <DummyMigration>()));
            var commit  = container.Commit(updated, signature, message);

            // Act
            var migrationScaffolder = new MigrationScaffolder(container, repository.RepositoryDescription,
                                                              serviceProvider.GetRequiredService <IRepositoryProvider>(), serviceProvider.GetRequiredService <ObjectRepositorySerializerFactory>());
            var migrators = migrationScaffolder.Scaffold(repository.CommitId, commit.CommitId, MigrationMode.Upgrade);

            // Assert
            Assert.That(migrators, Has.Count.EqualTo(1));
            Assert.That(migrators[0].CommitId, Is.EqualTo(commit.CommitId));
            Assert.That(migrators[0].Mode, Is.EqualTo(MigrationMode.Upgrade));
            Assert.That(migrators[0].Migrations, Has.Count.EqualTo(1));
        }
예제 #11
0
        public void MigrationScaffolderDetectsRequiredChanges(IFixture fixture, IServiceProvider serviceProvider, ObjectRepository sut, Signature signature, string message)
        {
            // Arrange
            var repositoryDescription = RepositoryFixture.GetRepositoryDescription();

            sut.SaveInNewRepository(signature, message, repositoryDescription);
            var updated = sut.With(i => i.Migrations.Add(fixture.Create <Migration>()));
            var commit  = sut.Commit(updated, signature, message);

            // Act
            var migrationScaffolder = new MigrationScaffolder(serviceProvider, repositoryDescription);
            var migrators           = migrationScaffolder.Scaffold(sut.CommitId, commit, MigrationMode.Upgrade);

            // Assert
            Assert.That(migrators, Has.Count.EqualTo(1));
            Assert.That(migrators[0].CommitId, Is.EqualTo(commit));
            Assert.That(migrators[0].Mode, Is.EqualTo(MigrationMode.Upgrade));
            Assert.That(migrators[0].Migrations, Has.Count.EqualTo(1));
        }
        public void VerifyDatabaseIsCompatibleWithModel()
        {
            // Arrange
            var context = new MyDbContext();
            // Act
            var isCompatible = context.Database.CompatibleWithModel(false);

            // Visual Assertion
            if (!isCompatible)
            {
                var config           = new MyDbMigrationsConfiguration();
                var scaffolder       = new MigrationScaffolder(config);
                var pendingMigration = scaffolder.Scaffold("MissingMigration");
                Trace.WriteLine("Missing Migration:");
                Trace.WriteLine("");
                Trace.WriteLine(pendingMigration.UserCode);
            }
            // Assert
            Assert.IsTrue(isCompatible, "The EF model is not compatible with the database. An EF migration needs to be created. See output for sample of missing migration.");
        }
예제 #13
0
        private static void GenerateDbMigration(string className)
        {
            Console.Write("Generating migration class......");

            var config     = new Configuration();
            var scaffolder = new MigrationScaffolder(config);
            var migration  = scaffolder.Scaffold(className);

            File.WriteAllText(migration.MigrationId + ".cs", migration.UserCode);
            File.WriteAllText(migration.MigrationId + ".Designer.cs", migration.DesignerCode);
            using (var writer = new ResXResourceWriter(migration.MigrationId + ".resx"))
            {
                foreach (var resource in migration.Resources)
                {
                    writer.AddResource(resource.Key, resource.Value);
                }
            }

            Console.Write("OK\n");
        }
예제 #14
0
        public async Task NoPendingMigrations(string dbName, string argumentName, MigrationContextFactory factory, IServiceProvider serviceProvider)
        {
            _dbName = dbName;

            var migrationContext = await factory.CreateMigrationContextAsync(argumentName, serviceProvider);

            var dbMigrator = migrationContext.GetDbMigrator();
            var migrations = dbMigrator.GetLocalMigrations();

            dbMigrator.Update(migrations.Last());

            var migrationScaffolder = new MigrationScaffolder(dbMigrator.Configuration);

            var migrationName = $"TestMigration{DateTimeOffset.UtcNow:yyyyMMddHHmmssFFFFFFF}";
            var result        = migrationScaffolder.Scaffold(migrationName);

            _output.WriteLine("Migration content:");
            _output.WriteLine(new string('-', 60));
            _output.WriteLine(result.UserCode);
            _output.WriteLine(new string('-', 60));

            Assert.Equal(
                $@"namespace {dbMigrator.Configuration.MigrationsNamespace}
{{
    using System;
    using System.Data.Entity.Migrations;
    
    public partial class {migrationName} : DbMigration
    {{
        public override void Up()
        {{
        }}
        
        public override void Down()
        {{
        }}
    }}
}}
", result.UserCode);
        }
예제 #15
0
        public virtual void AddMigration(
            String migrationName,
            String contextTypeName,
            String rootNamespace,
            String projectDir)
        {
            var contextType       = GetContextType(contextTypeName);
            var configurationType = GetConfigurationType(contextType);

            var configuration = CreateConfiguration(configurationType);
            var scaffolder    = new MigrationScaffolder(configuration);

            var migration = scaffolder.Scaffold(migrationName);

            var migrationDirectory    = Path.Combine(projectDir, migration.Directory);
            var migrationFile         = Path.Combine(migrationDirectory, migration.MigrationId + "." + migration.Language);
            var migrationMetadataFile = Path.Combine(migrationDirectory, migration.MigrationId + ".Designer." + migration.Language);

            var designerCode =
                migration.DesignerCode
                .Replace("private readonly ResourceManager", "//private readonly ResourceManager");

            foreach (var replaceKey in new[] { "Source", "Target" })
            {
                if (migration.Resources.ContainsKey(replaceKey))
                {
                    var code = String.Format("Resources.GetString(\"{0}\")", replaceKey);

                    var valueString = String.Format("\"{0}\"", migration.Resources[replaceKey]);

                    designerCode = designerCode.Replace(code, valueString);
                }
            }

            Directory.CreateDirectory(migrationDirectory);
            File.WriteAllText(migrationFile, migration.UserCode);
            File.WriteAllText(migrationMetadataFile, designerCode);
        }
        public static MigrationInfo CreateMigrations(string migrationName, string migrationDirectory, Func <string, IResourceWriter> createResourceWriter)
        {
            var configuration = new Configuration();
            var scaffolder    = new MigrationScaffolder(configuration);
            var migration     = scaffolder.Scaffold(migrationName);

            var codeFileName     = migration.MigrationId + ".cs";
            var designerFileName = migration.MigrationId + ".Designer.cs";
            var resourceFileName = migration.MigrationId + ".resx";

            File.WriteAllText($"{migrationDirectory}/{codeFileName}", migration.UserCode);
            File.WriteAllText($"{migrationDirectory}/{designerFileName}", migration.DesignerCode);

            using (var resourceWriter = createResourceWriter($"{migrationDirectory}/{resourceFileName}"))
            {
                foreach (var resource in migration.Resources)
                {
                    resourceWriter.AddResource(resource.Key, resource.Value);
                }
            }

            return(new MigrationInfo(codeFileName, designerFileName, resourceFileName));
        }
예제 #17
0
        public override async Task <int> Main()
        {
            try
            {
                Environment.CurrentDirectory = PathManager.FindResource();
            }
            catch (FileNotFoundException ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine("Use `nfpm scaffold` to generate a NFive plugin in this directory");

                return(1);
            }

            AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
            {
                if (args.Name.Contains(".resources"))
                {
                    return(null);
                }

                var fileName = args.Name.Substring(0, args.Name.IndexOf(",", StringComparison.InvariantCultureIgnoreCase)) + ".dll";

                if (File.Exists(fileName))
                {
                    return(Assembly.Load(File.ReadAllBytes(fileName)));
                }

                var path = Directory.EnumerateFiles("plugins", "*.dll", SearchOption.AllDirectories).FirstOrDefault(f => Path.GetFileName(f) == fileName);

                if (string.IsNullOrEmpty(path))
                {
                    throw new FileLoadException(args.Name);
                }

                return(Assembly.Load(File.ReadAllBytes(path)));
            };

            DTE dte = null;

            try
            {
                if (!File.Exists(this.Sln))
                {
                    this.Sln = Directory.EnumerateFiles(Environment.CurrentDirectory, "*.sln", SearchOption.TopDirectoryOnly).FirstOrDefault();
                }
                if (this.Sln == null || !File.Exists(this.Sln))
                {
                    this.Sln = Input.String("Visual Studio SLN solution file");
                }

                Console.Write("Searching for existing Visual Studio instance...");

                dte = VisualStudio.GetInstances().FirstOrDefault(env => env.Solution.FileName == this.Sln);

                if (dte != default)
                {
                    Console.WriteLine(" found");
                }
                else
                {
                    Console.WriteLine(" not found");
                    Console.WriteLine("Starting new Visual Studio instance...");

                    dte = (DTE)Activator.CreateInstance(Type.GetTypeFromProgID("VisualStudio.DTE", true), true);

                    this.existingInstance = false;
                }

                Console.WriteLine("Opening solution");

                var solution = Retry.Do(() => dte.Solution);

                if (!Retry.Do(() => solution.IsOpen))
                {
                    Retry.Do(() => solution.Open(this.Sln));
                }

                Console.WriteLine("Building solution");

                solution.SolutionBuild.Build(true);

                Console.WriteLine("Searching for projects");

                var pp = Retry.Do(() => solution.Projects.Cast <Project>().ToList());

                var ppp = Retry.Do(() => pp.Where(p => !string.IsNullOrWhiteSpace(p.FullName)).ToList());

                foreach (var project in ppp)
                {
                    Console.WriteLine($"  Analyzing project {Retry.Do(() => project.Name)}...");

                    var projectPath = Path.GetDirectoryName(Retry.Do(() => project.FullName)) ?? string.Empty;
                    var outputPath  = Path.GetFullPath(Path.Combine(projectPath, Retry.Do(() => project.ConfigurationManager.ActiveConfiguration.Properties.Item("OutputPath").Value.ToString()), Retry.Do(() => project.Properties.Item("OutputFileName").Value.ToString())));

                    var asm = Assembly.Load(File.ReadAllBytes(outputPath));
                    if (!this.Sdk && asm.GetCustomAttribute <ServerPluginAttribute>() == null)
                    {
                        continue;
                    }

                    var contextType = asm.DefinedTypes.FirstOrDefault(t => t.BaseType != null && t.BaseType.IsGenericType && t.BaseType.GetGenericTypeDefinition() == typeof(EFContext <>));
                    if (contextType == default)
                    {
                        continue;
                    }

                    Console.WriteLine($"    Loaded {outputPath}");

                    Console.WriteLine($"    Found DB context: {contextType.Name}");

                    var props = contextType
                                .GetProperties()
                                .Where(p =>
                                       p.CanRead &&
                                       p.CanWrite &&
                                       p.PropertyType.IsGenericType &&
                                       p.PropertyType.GetGenericTypeDefinition() == typeof(DbSet <>) &&
                                       p.PropertyType.GenericTypeArguments.Any(t => !string.IsNullOrEmpty(t.Namespace) && t.Namespace.StartsWith("NFive.SDK."))) // TODO
                                .Select(t => $"dbo.{t.Name}")                                                                                                    // TODO
                                .ToArray();

                    if (!this.Sdk)
                    {
                        Console.WriteLine($"    Excluding tables: {string.Join(", ", props)}");
                    }

                    var migrationsPath = "Migrations";

                    if (!Directory.Exists(Path.Combine(projectPath, migrationsPath)))
                    {
                        migrationsPath = Input.String("Migration source code folder", "Migrations");                                                                                   // TODO: Validate
                    }
                    var @namespace = $"{project.Properties.Item("RootNamespace").Value}.{migrationsPath}";

                    if (asm.DefinedTypes.Any(t => t.BaseType != null && t.BaseType == typeof(DbMigration) && t.Namespace == @namespace && t.Name == this.Name))
                    {
                        throw new Exception($"A migration named \"{this.Name}\" already exists at \"{@namespace}.{this.Name}\", please use another migration name.");
                    }

                    Console.WriteLine("    Generating migration...");

                    var migrationsConfiguration = new DbMigrationsConfiguration
                    {
                        AutomaticMigrationDataLossAllowed = false,
                        AutomaticMigrationsEnabled        = false,
                        CodeGenerator       = new NFiveMigrationCodeGenerator(this.Sdk ? new string[] { } : props),
                        ContextType         = contextType,
                        ContextKey          = $"{@namespace}.Configuration",
                        MigrationsAssembly  = asm,
                        MigrationsDirectory = migrationsPath,
                        MigrationsNamespace = @namespace,
                        TargetDatabase      = new DbConnectionInfo(this.Database, "MySql.Data.MySqlClient")
                    };

                    var ms = new MigrationScaffolder(migrationsConfiguration);

                    if (this.RunMigrations)
                    {
                        var migrator = new DbMigrator(migrationsConfiguration);

                        if (migrator.GetPendingMigrations().Any())
                        {
                            Console.WriteLine("    Running existing migrations...");

                            foreach (var migration in migrator.GetPendingMigrations())
                            {
                                Console.WriteLine($"        Running migration: {migration}");

                                migrator.Update(migration);
                            }
                        }
                    }

                    Console.WriteLine("    Scaffolding migration...");

                    var src = ms.Scaffold(this.Name, false);

                    var file = Path.Combine(projectPath, migrationsPath, $"{src.MigrationId}.{src.Language}");

                    Console.WriteLine($"    Writing migration: {file}");

                    File.WriteAllText(file, src.UserCode);

                    Console.WriteLine("    Updating project...");

                    project.ProjectItems.AddFromFile(file);
                    project.Save();
                }

                Console.WriteLine("Building solution...");

                solution.SolutionBuild.Build(true);

                if (!this.existingInstance)
                {
                    Console.WriteLine("Quitting Visual Studio instance");

                    dte.Quit();
                }

                Console.WriteLine("Done");

                return(await Task.FromResult(0));
            }
            catch (ReflectionTypeLoadException ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine(string.Join(Environment.NewLine, ex.LoaderExceptions.Select(e => e.Message)));

                return(1);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);

                return(1);
            }
            finally
            {
                if (!this.existingInstance)
                {
                    dte.Quit();
                }
            }
        }
예제 #18
0
    /// <summary>
    ///     The entry point of the program, where the program control starts and ends.
    /// </summary>
    public static void Main()
    {
        // USER INPUT /////////////////////////////////////////////////////////////////////////////////
        // Always first create a new database migration with DatabaseStep.ADD_MIGRATION,
        // and include the created files in the project and set resource file to EmbeddedResource.
        // After creating a migration run UPDATE_DATABASE to update the database.
        const DatabaseStep step = DatabaseStep.UPDATE_DATABASE;
        // Specify the name of the database migration in case of ADD-MIGRATION.
        // Note: Make sure to create a new name for each new migration.
        //       After creating migration include the files in the folder by right clicking on
        //       Zk.Migrations and selecting "Add files from folder". Then add the .cs, .resx and
        //       .Designer.cs files with the name specified below.
        //       Last but not least set the .resx file's build action to EmbeddedResource by right
        //       clicking on it.
        // Make sure that the Setup.postgresql script has run manually to create the database user.
        const string MIGRATION_NAME = "CalendarAndUser";
        // END USER INPUT /////////////////////////////////////////////////////////////////////////////
        // Get executing path from which the location of the Update_Scripts and new Migrations can be determined.
        var executingPath = AppDomain.CurrentDomain.BaseDirectory;

        // Add a new migration (PowerShell: Add-Migration)
        if (step == DatabaseStep.ADD_MIGRATION)
        {
            // Initialize the wrapper classes around the Entity Framework PowerShell API.
            var config     = new Configuration();
            var scaffolder = new MigrationScaffolder(config);
            var migration  = scaffolder.Scaffold(MIGRATION_NAME);

            // Place migration code in main project "Migrations" folder and migration scripts in "App_Data"
            var migrationsPath = Regex.Replace(executingPath, "bin/.*", "");

            // Write migrations
            File.WriteAllText(migrationsPath + MIGRATION_NAME + ".cs", migration.UserCode);
            File.WriteAllText(migrationsPath + MIGRATION_NAME + ".Designer.cs", migration.DesignerCode);
            using (var writer = new ResXResourceWriter(migrationsPath + MIGRATION_NAME + ".resx"))
            {
                foreach (var resource in migration.Resources)
                {
                    writer.AddResource(resource.Key, resource.Value);
                }
            }
            Console.WriteLine("EF code migration {0} written to Migrations folder...\n\n" +
                              "Next step is to include the .cs, .resx and .Designer.cs file in the project" +
                              "by right clicking on the project and selecting " +
                              "\"Add files from folder.\"\n" +
                              "Then right click on {0}.resx and set build action to \"EmbeddedResource\""
                              , migration.MigrationId);
        }
        else if (step == DatabaseStep.CREATE_SCRIPT)
        {
            var config   = new Configuration();
            var migrator = new DbMigrator(config);
            var scriptor = new MigratorScriptingDecorator(migrator);
            // Determine name of the previous run migration if exists.
            string lastMigration = migrator.GetDatabaseMigrations().LastOrDefault();
            // Get the script
            string script = scriptor.ScriptUpdate(sourceMigration: lastMigration, targetMigration: MIGRATION_NAME);
            // Create the PostgreSQL update script based on last migration on database and
            // current migration.
            string formattedScript = string.Format
                                         ("/* * * * * * * * * * * * * * * * * * * * * * *\n" +
                                         " *\n" +
                                         " * Migration:\t\t{0}\n *\n" +
                                         " * Date and time:\t{1}\n" +
                                         " *\n" +
                                         " * * * * * * * * * * * * * * * * * * * * * * */\n\n" +
                                         "{2}",
                                         MIGRATION_NAME,
                                         DateTime.Now,
                                         script);
            // Write string to file in Migrations folder of main project
            var updateScriptPath = Regex.Replace(executingPath, "Zk.Migrations/.*", "Zk/App_Data/Migrations/");
            File.WriteAllText(updateScriptPath + MIGRATION_NAME + ".postgresql", formattedScript);
            Console.WriteLine("Update script {0}.postgresql written to Zk/App_Data/Migrations folder.\n" +
                              "Please include the script by right clicking on the folder and selecting " +
                              "\"Add files to folder\"," +
                              "\nIt is recommended to prefix the filename with the current datetime.",
                              MIGRATION_NAME);
        }
        // If a new migration is created the database can be updated. (PowerShell: Update-Database)
        else if (step == DatabaseStep.UPDATE_DATABASE)
        {
            var config   = new Configuration();
            var migrator = new DbMigrator(config);
            // Write to database
            migrator.Update();
            // Show which migrations were applied.
            var migrationNames = string.Join(", ", migrator.GetDatabaseMigrations().ToArray().First());
            Console.WriteLine("Applied migration {0} to database.", migrationNames);
        }
    }