2012-05-03 11 views
14

Necesito poder publicar un proyecto SSDT programáticamente. Estoy buscando utilizar Microsoft.Build para hacerlo, pero no puedo encontrar ninguna documentación. Parece bastante simple crear el .dacpac, pero ¿cómo podría publicarlo en una base de datos existente o al menos en un archivo .sql? La idea es hacer que haga lo que hace cuando haga clic derecho en el proyecto y seleccione publicar. Se debe comparar con una base de datos seleccionada y generar un script de actualización.Uso de Microsoft.Build.Evaluation para publicar un proyecto de base de datos (.sqlproj)

Esto es lo que tengo hasta ahora para crear el .dacpac:

partial class DBDeploy 
{ 
    Project project; 


    internal void publishChanges() 
    { 
    Console.WriteLine("Building project " + ProjectPath); 
    Stopwatch sw = new Stopwatch(); 
    sw.Start(); 

    project = ProjectCollection.GlobalProjectCollection.LoadProject(ProjectPath); 
    project.Build(); 
    //at this point the .dacpac is built and put in the debug folder for the project 

    sw.Stop(); 
    Console.WriteLine("Project build Complete. Total time: {0}", sw.Elapsed.ToString()); 

    } 
} 

Esencialmente estoy tratando de hacer lo que esta MSBuild Example espectáculos, pero en el código.

Disculpa que esto es todo lo que tengo. La documentación en las clases de compilación es muy pobre. Cualquier ayuda sería apreciada.

Gracias.

Respuesta

3

Necesitamos una forma de decirle a msbuild cómo y dónde publicar. Abra su proyecto en Visual Studio y comience a Publish. Ingrese toda la información necesaria en el cuadro de diálogo, incluida la información de conexión de su base de datos y cualquier valor de variable SQLCMD personalizado. Save Profile As... a un archivo, p. Northwind.publish.xml. (. A continuación, puede Cancel) Ahora puede utilizar este y el archivo de proyecto para construir y publicar:

// Create a logger. 
FileLogger logger = new FileLogger(); 
logger.Parameters = @"logfile=Northwind.msbuild.log"; 
// Set up properties. 
var projects = ProjectCollection.GlobalProjectCollection; 
projects.SetGlobalProperty("Configuration", "Debug"); 
projects.SetGlobalProperty("SqlPublishProfilePath", @"Northwind.publish.xml"); 
// Load and build project. 
var dbProject = ProjectCollection.GlobalProjectCollection.LoadProject(@"Northwind.sqlproj"); 
dbProject.Build(new[]{"Build", "Publish"}, new[]{logger}); 

Esto puede tomar un tiempo y puede aparecer a atascarse. Se paciente. :)

+1

Necesitaba hacer referencia a los ensamblados 'Microsoft.Build' y' Microsoft.Build.Framework' para que este código funcione. – Sam

+0

Asegúrese de verificar el valor de retorno de 'Build' para ver si fue exitoso o no. – Sam

+0

Para monitorear eventos de compilación, use 'ConfigurableForwardingLogger' y establezca' BuildEventRedirector' en un 'IEventRedirector' personalizado. Puede verificar si hay errores al verificar si 'buildEvent' es' BuildErrorEventArgs'. – Sam

1

Debe usar SqlPackage.exe para publicar su dacpac.

SqlPackage.exe 
    /Action:Publish 
    /SourceFile:C:/file.dacpac 
    /TargetConnectionString:[Connection string] 

también en lugar de pasar demasiados parámetros se podía guardar la configuración en DAC perfil de publicación (esto se puede hacer a partir de Visual Studio)

+1

'should' ... debería ser' could' :) – ppumkin

19

que tenía que hacer algo similar a esto porque VSDBCMD que usamos anteriormente no se implementa en SQL Server 2012 y necesitamos su compatibilidad. Lo que encontré fue el ensamblado Microsoft.SqlServer.Dac que parece venir como parte de las herramientas de datos de SQL Server (http://msdn.microsoft.com/en-us/data/tools.aspx)

Cuando ejecuta esto en el equipo cliente, necesitará la versión completa del .NET 4 framework y los tipos de CLR de SQL y el paquete de SQL T-SQL ScriptDOM encontrar aquí: http://www.microsoft.com/en-us/download/details.aspx?id=29065 Código

a continuación es de una maqueta que hice para probar el nuevo método de implementación y despliega un archivo .dacpac dado

using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 
    using Microsoft.SqlServer.Dac; 
    using System.IO; 

    namespace ConsoleApplication3 
    { 
     class Program 
     { 
      private static TextWriter output = new StreamWriter("output.txt", false); 
      static void Main(string[] args) 
      { 

       Console.Write("Connection String:"); 
       //Class responsible for the deployment. (Connection string supplied by console input for now) 
       DacServices dbServices = new DacServices(Console.ReadLine()); 

       //Wire up events for Deploy messages and for task progress (For less verbose output, don't subscribe to Message Event (handy for debugging perhaps?) 
       dbServices.Message += new EventHandler<DacMessageEventArgs>(dbServices_Message); 
       dbServices.ProgressChanged += new EventHandler<DacProgressEventArgs>(dbServices_ProgressChanged); 


       //This Snapshot should be created by our build process using MSDeploy 
       Console.WriteLine("Snapshot Path:"); 

       DacPackage dbPackage = DacPackage.Load(Console.ReadLine()); 




       DacDeployOptions dbDeployOptions = new DacDeployOptions(); 
       //Cut out a lot of options here for configuring deployment, but are all part of DacDeployOptions 
       dbDeployOptions.SqlCommandVariableValues.Add("debug", "false"); 


       dbServices.Deploy(dbPackage, "trunk", true, dbDeployOptions); 
       output.Close(); 

      } 

      static void dbServices_Message(object sender, DacMessageEventArgs e) 
      { 
       output.WriteLine("DAC Message: {0}", e.Message); 
      } 

      static void dbServices_ProgressChanged(object sender, DacProgressEventArgs e) 
      { 
       output.WriteLine(e.Status + ": " + e.Message); 
      } 
     } 
    } 

Esto parece para trabajar en todas las versiones de SQL Server desde 2005 en adelante. Hay un conjunto similar de objetos disponibles en Microsoft.SqlServer.Management.Dac, sin embargo, creo que esto está en la versión anterior de DACFx y no está incluido en la última versión. Así que usa la última versión si puedes.

+1

Brillante, usar los ensamblajes DACPAC me permite tomar el control total de la implementación. ¡También es útil para pruebas de integración! – Raffaeu

+0

¡Finalmente, una respuesta sensata! Gracias. Solo quiero agregar que necesita copiar/referenciar el 'sqlserver.dac.dll' de' Microsoft Visual Studio ??. 0 \ Common7 \ IDE \ Extensions \ Microsoft \ SQLDB \ DAC \ 120' - Funciona muy bien, exactamente lo que necesitaba, tan simple y rápido. Esto debe ser aceptado! – ppumkin

+0

¿Alguna experiencia con establecer la bandera "upgradeExisting" en falso? Recibo una excepción diciéndome "No se puede implementar en una base de datos existente cuando la actualización se ha deshabilitado". Pero quiero que DacServices elimine primero la base de datos. No funciona, incluso si agrego opciones con CreateNewDatabase = true – Peter

1

Quería construir y publicar una base de datos basada en un archivo sqlproj y registrar información útil para la consola. Aquí es a lo que llegué:

using Microsoft.Build.Framework; 
using Microsoft.Build.Execution; 

public void UpdateSchema() { 
    var props = new Dictionary<string, string> { 
     { "UpdateDatabase", "True" }, 
     { "PublishScriptFileName", "schema-update.sql" }, 
     { "SqlPublishProfilePath", "path/to/publish.xml") } 
    }; 

    var projPath = "path/to/database.sqlproj"; 

    var result = BuildManager.DefaultBuildManager.Build(
     new BuildParameters { Loggers = new[] { new ConsoleLogger() } }, 
     new BuildRequestData(new ProjectInstance(projPath, props, null), new[] { "Publish" })); 

    if (result.OverallResult == BuildResultCode.Success) { 
     Console.WriteLine("Schema update succeeded!"); 
    } 
    else { 
     Console.ForegroundColor = ConsoleColor.Red; 
     Console.WriteLine("Schema update failed!"); 
     Console.ResetColor(); 
    } 
} 

private class ConsoleLogger : ILogger 
{ 
    public void Initialize(IEventSource eventSource) { 
     eventSource.ErrorRaised += (sender, e) => { 
      Console.ForegroundColor = ConsoleColor.Red; 
      Console.WriteLine(e.Message); 
      Console.ResetColor(); 
     }; 
     eventSource.MessageRaised += (sender, e) => { 
      if (e.Importance != MessageImportance.Low) 
       Console.WriteLine(e.Message); 
     }; 
    } 
    public void Shutdown() { } 
    public LoggerVerbosity Verbosity { get; set; } 
    public string Parameters { get; set; } 
} 

Esto es para .NET 4 y superiores. Asegúrese de incluir referencias de ensamblaje en Microsoft.Build y Microsoft.Build.Framework.

Cuestiones relacionadas