2013-12-14 2 views
4

내 특정 문제는 어떻게 Entity Framework의 빌드 프로세스에서 "추가 마이그레이션"을 자동화 할 수 있는지입니다. 이 연구에서는, 그것은 대부분 가능성이 접근 방식은 다음 단계Visual Studio 2013에서 패키지 관리자 콘솔을 자동화하는 방법

  1. 열기 2013
  2. 가 실행 Visual Studio에서 솔루션을 자동화의 라인을 따라 뭔가 것 같다 "추가 마이그레이션 blahblah"를 패키지 관리자 콘솔에서 (가장 가능성 추가 기능 vsextention)를 통해
  3. 궁극적 뒤에 추가 마이그레이션 실행 셋업이 꽤 필요이 초기 접근 방식은 내 자신의 연구와 this question의 PowerShell 스크립트를 기반으로하는 솔루션

를 닫습니다. Visual Studio는 패키지 관리자 콘솔을 만들고 DTE 개체를 사용할 수있게 만들 때이 설정을 자동으로 수행합니다. Visual Studio 외부에서 해당 설치를 복제하지 않으려합니다. "이 콘솔에 입력 한 것처럼이 텍스트를 전송하고 실행됩니다"

는 솔루션

한 가지 경로는,이 표시되지 않는 NuGet API를 연구에서는이 답 스택 오버 플로우 question

입니다 . 나는 Visual Studio와 NuGet 사이의 경계선에서 명확하지 않다. 그래서 나는 이것이 거기에있을 것이라고 확신하지 못한다.

"Pacakage Manager Console"은 패키지 관리자 콘솔의 "$ dte.Windows"명령을 통해 역설적으로 찾을 수 있지만 VS 2013 창에서는 "Microsoft.VisualStudio.Platform .WindowManagement.DTE.WindowBase "를 참조하십시오. 그 안에 물건 텍스트가 있다면 NuGetConsole이되어야한다고 생각합니다. 구현 "PowerConsoleToolWindow"source code 검토를 통해 텍스트가 어떻게 채워지는지 명확하지 않지만 현재 내가 무엇인지 잘 모릅니다. 보고.

가 이

최악의 경우, 내가 this question의 라인을 따라 여기에 물건을 키려고 다시 떨어질 것이다하지만 실질적으로 빌드 프로세스를 둘러싼 자동화 복잡하기 때문에 안함 것이다.

그 존재의 모든를 said

  1. 코드를 통해 명령을 Packag로 스트리밍 할 수 있습니까? Visual Studio에서 Entity Framework "추가 - 마이그레이션"명령을 완벽하게 초기화하고 지원할 수있는 관리자 콘솔? 사전에 어떤 제안, 조언, 도움, 비 불량

감사합니다,

+0

SendKeys를 사용하여 키 누름을 WindowBase로 밀어 넣으려고 했습니까? http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys(v=vs.110).aspx – jessehouwing

+0

나는 SendKeys를 시도 했었거나 시도하지 않았다. 나는 나의 마지막 도랑 해결책으로 그것을보고 있었다. 나는 아래의 접근법을 먼저 생각해 냈다. –

+0

PMC 윈도우를 얻으려면,'DTE.ExecuteCommand ("View.PackageManagerConsole")'을 호출하면,'DTE.ActiveWindow'가 PMC 윈도우가됩니다. 나는 아직도 그것에 텍스트를 보내는 방법을 알아 내지 못했다. – Jonathan

답변

5

나를 AddMigrationCommand에 시작하는 엔티티 프레임 워크 코드로 추적하는 것이었다 근무 접근. cs를 EntityFramework.Powershell 프로젝트에 추가하고 EntityFramework 프로젝트에 후크를 찾은 다음 Powershell 종속성이 없도록 해당 후크가 작동하도록합니다. 당신이 뭔가를 얻을 수

...

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); 

    } 

당신은 전화로 전달하는 프로젝트 개체를 찾기 위해 DTE 개체에 도착 this question를 사용하고 거기에서 할 수 있습니다.

0

이것은 "어려운 부분"에 대해 감사해야 할 John의 대답에 대한 업데이트입니다. 그러나 마이그레이션을 생성하고 제공된 프로젝트 (프로젝트는 이전에 빌드해야 함) 로의 마이그레이션을 추가하는 완전한 예가 여기에 있습니다. 방법으로 Add-Migration InitialBase -IgnoreChanges 것 : 나는 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); 
    } 
} 

나는 때문에 기본 프로젝트와 공유 entites의, 내 프로젝트 템플릿의 IWizard 구현이를 실행합니다. 변경 내용을 포함하려면 scaffolder.Scaffold("InitialBase", true)scaffolder.Scaffold("InitialBase", false)으로 변경하십시오.

관련 문제