How to automate the package manager console in Visual Studio 2013

My specific problem is how I can automate add-migration during the build process for the Entity Framework. When exploring this, it seems that the most likely approach is something like automating these steps.

  • Open the solution in Visual Studio 2013
  • Run "Add-Migration blahblah" in the package manager console (most likely using the extension extension)
  • Close the solution

This initial approach is based on my own research and on this issue , the powershell script ultimately requires quite a few tweaks to start-up migration, Visual Studio automatically does this when creating the package manager console and creating the DTE object. I would rather not try to duplicate this setting outside of Visual Studio.

One possible way to solve is an incomplete stack overflow question

When exploring the NuGet API, it does not seem to have β€œsending this text, and it will run as if it were entered into the console.” I don't understand what Visual Studio vs NuGet is, so I'm not sure if that is what would be there.

I can easily find the "Pacakage Manager Console" through the "$ dte.Windows" command in the package manager console, but in the VS 2013 window this collection gives me objects that are "Microsoft.VisualStudio.Platform. WindowManagement.DTE.WindowBase". If it has style text, I think I need it to be NuGetConsole.Implementation.PowerConsoleToolWindow "by looking at the source code I don’t understand how the text will be filled, but I am not at all familiar with what I see.

In the worst case, I will return to try to impose keys on it in accordance with this issue , but would prefer not to do this, as this will significantly complicate the automation of the environment the assembly process.

All said

  • Is it possible to pass commands through code to the package manager console in Visual Studio, which is fully initialized and can support the add-redirect command in the Entity Framework?

Thanks for any suggestions, tips, help, not abuse in advance,

John

+4
source share
2 answers

The approach that worked for me was to track the code of the entity frame, starting with AddMigrationCommand.cs in the EntityFramework.Powershell project and finding the hooks in the EntityFramework project and then getting these hooks to work, so there is no Powershell dependency.

You can get something like ...

public static void RunIt(EnvDTE.Project project, Type dbContext, Assembly migrationAssembly, string migrationDirectory, string migrationsNamespace, string contextKey, string migrationName) { DbMigrationsConfiguration migrationsConfiguration = new DbMigrationsConfiguration(); migrationsConfiguration.AutomaticMigrationDataLossAllowed = false; migrationsConfiguration.AutomaticMigrationsEnabled = false; migrationsConfiguration.CodeGenerator = new CSharpMigrationCodeGenerator(); //same as default migrationsConfiguration.ContextType = dbContext; //data migrationsConfiguration.ContextKey = contextKey; migrationsConfiguration.MigrationsAssembly = migrationAssembly; migrationsConfiguration.MigrationsDirectory = migrationDirectory; migrationsConfiguration.MigrationsNamespace = migrationsNamespace; System.Data.Entity.Infrastructure.DbConnectionInfo dbi = new System.Data.Entity.Infrastructure.DbConnectionInfo("DataContext"); migrationsConfiguration.TargetDatabase = dbi; MigrationScaffolder ms = new MigrationScaffolder(migrationsConfiguration); ScaffoldedMigration sf = ms.Scaffold(migrationName, false); } 

You can use this question to get to the dte object and from there to find the project object to pass to the call.

+5
source

This is a message for John, whom I must thank for the "difficult role", but here is a complete example that creates a transfer and adds that the transfer to the supplied project (the project must be built earlier) in the same way as Add-Migration InitialBase -IgnoreChanges :

 public void ScaffoldedMigration(EnvDTE.Project project) { var migrationsNamespace = project.Properties.Cast<Property>() .First(p => p.Name == "RootNamespace").Value.ToString() + ".Migrations"; var assemblyName = project.Properties.Cast<Property>() .First(p => p.Name == "AssemblyName").Value.ToString(); var rootPath = Path.GetDirectoryName(project.FullName); var assemblyPath = Path.Combine(rootPath, "bin", assemblyName + ".dll"); var migrationAssembly = Assembly.Load(File.ReadAllBytes(assemblyPath)); Type dbContext = null; foreach(var type in migrationAssembly.GetTypes()) { if(type.IsSubclassOf(typeof(DbContext))) { dbContext = type; break; } } var migrationsConfiguration = new DbMigrationsConfiguration() { AutomaticMigrationDataLossAllowed = false, AutomaticMigrationsEnabled = false, CodeGenerator = new CSharpMigrationCodeGenerator(), ContextType = dbContext, ContextKey = migrationsNamespace + ".Configuration", MigrationsAssembly = migrationAssembly, MigrationsDirectory = "Migrations", MigrationsNamespace = migrationsNamespace }; var dbi = new System.Data.Entity.Infrastructure .DbConnectionInfo("ConnectionString", "System.Data.SqlClient"); migrationsConfiguration.TargetDatabase = dbi; var scaffolder = new MigrationScaffolder(migrationsConfiguration); ScaffoldedMigration migration = scaffolder.Scaffold("InitialBase", true); var migrationFile = Path.Combine(rootPath, migration.Directory, migration.MigrationId + ".cs"); File.WriteAllText(migrationFile, migration.UserCode); var migrationItem = project.ProjectItems.AddFromFile(migrationFile); var designerFile = Path.Combine(rootPath, migration.Directory, migration.MigrationId + ".Designer.cs"); File.WriteAllText(designerFile, migration.DesignerCode); var designerItem = project.ProjectItems.AddFromFile(migrationFile); foreach(Property prop in designerItem.Properties) { if (prop.Name == "DependentUpon") prop.Value = Path.GetFileName(migrationFile); } var resxFile = Path.Combine(rootPath, migration.Directory, migration.MigrationId + ".resx"); using (ResXResourceWriter resx = new ResXResourceWriter(resxFile)) { foreach (var kvp in migration.Resources) resx.AddResource(kvp.Key, kvp.Value); } var resxItem = project.ProjectItems.AddFromFile(resxFile); foreach (Property prop in resxItem.Properties) { if (prop.Name == "DependentUpon") prop.Value = Path.GetFileName(migrationFile); } } 

I do this in my implementation of the IWizard project, where I start the migration using IgnoreChanges due to sharing with the base project. Change scaffolder.Scaffold("InitialBase", true) to scaffolder.Scaffold("InitialBase", false) if you want to enable the changes.

0
source

Source: https://habr.com/ru/post/1486087/


All Articles