2012-05-03 16 views
14

Muszę być w stanie programowo opublikować projekt SSDT. Używam Microsoft.Build do tego, ale nie mogę znaleźć żadnej dokumentacji. Wydaje się dość proste utworzenie pliku .dacpac, ale w jaki sposób powinienem opublikować istniejącą bazę danych lub przynajmniej plik .sql. Chodzi o to, aby zrobić to, co robi, gdy kliknę prawym przyciskiem myszy na projekcie i wybierz opcję publikowania. Należy porównać z wybraną bazą danych i wygenerować skrypt aktualizacyjny.Korzystanie z Microsoft.Build.Evaluation do opublikowania projektu bazy danych (.sqlproj)

To, co mam tak daleko, aby utworzyć .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()); 

    } 
} 

Zasadniczo staram się robić co w tym MSBuild Example pokazy, ale w kodzie.

Przepraszam, że to wszystko, co mam. Dezinstalacja na klasach Build jest bardzo słaba. Każda pomoc będzie doceniona.

Dzięki.

Odpowiedz

3

Potrzebujemy sposobu, aby powiedzieć msbuild jak i gdzie opublikować. Otwórz swój projekt w Visual Studio i zacznij od Publish go. Wprowadź wszystkie potrzebne informacje w oknie dialogowym, w tym informacje o połączeniu DB i wszelkie niestandardowe wartości zmiennych SQLCMD. Save Profile As... do pliku, np. Northwind.publish.xml. (. Być może wtedy Cancel) Teraz możemy korzystać z tej i plik projektu do budowy i rozpatrzenie:

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

To może zająć trochę czasu i może pojawić się utknąć. Bądź cierpliwy. :)

+1

Musiałem odwołać się do zespołów "Microsoft.Build" i "Microsoft.Build.Framework', aby ten kod zadziałał. – Sam

+0

Upewnij się, aby sprawdzić wartość zwracaną przez 'Build', aby sprawdzić, czy udało się, czy nie. – Sam

+0

Aby monitorować zdarzenia kompilacji, użyj 'ConfigurableForwardingLogger' i ustaw' BuildEventRedirector' na niestandardowy 'IEventRedirector'. Możesz sprawdzić błędy, sprawdzając czy 'buildEvent' jest' BuildErrorEventArgs'. – Sam

1

Powinieneś użyć SqlPackage.exe, aby opublikować swój dacpac.

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

Również zamiast przekazywać zbyt wiele parametrów można zapisać ustawienia na DAC Publish profilu (można to zrobić z visual studio)

+1

'powinien' ... powinien być' mógł' :) – ppumkin

19

musiałem zrobić coś podobnego do tego, ponieważ VSDBCMD które poprzednio używany nie wdraża się do SQL Server 2012 i musieliśmy go wspierać. Znalazłem zestaw Microsoft.SqlServer.Dac, który wydaje się być częścią narzędzi danych SQL Server (http://msdn.microsoft.com/en-us/data/tools.aspx)

Po uruchomieniu tego na komputerze klienckim potrzebna jest pełna wersja platformy .NET 4 i tutaj typy CLR SQL i T-SQL SQL ScriptDOM paczka: http://www.microsoft.com/en-us/download/details.aspx?id=29065

Kod poniżej jest od makieta zrobiłem do testowania nowej metody wdrażania i wdraża dany plik .dacpac

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

wydaje się to pracować na wszystkich wersjach SQL Server od 2005 roku i wyżej. Istnieje podobny zestaw obiektów dostępnych w Microsoft.SqlServer.Management.Dac, jednak uważam, że jest to w poprzedniej wersji DACFx i nie jest zawarte w najnowszej wersji. Więc jeśli chcesz, użyj najnowszej wersji.

+1

Świetnie, używając zestawów DACPAC, pozwala mi to na przejęcie pełnej kontroli nad wdrożeniem. Przydaje się również w testach integracyjnych! – Raffaeu

+0

Wreszcie rozsądna odpowiedź! Dzięki - Po prostu chcesz dodać, że musisz skopiować/odwołać 'sqlserver.dac.dll' z' Microsoft Visual Studio ??. 0 \ Common7 \ IDE \ Rozszerzenia \ Microsoft \ SQLDB \ DAC \ 120' - Działa naprawdę dobrze, dokładnie to, czego potrzebowałem, tak proste i szybkie. To powinno zostać zaakceptowane! – ppumkin

+0

Jakieś doświadczenie z ustawieniem flagi "upgradeExisting" na false? Otrzymuję wyjątek mówiący mi "Nie można wdrożyć w istniejącej bazie danych po wyłączeniu aktualizacji". Ale chcę, aby DacServices najpierw usunął bazę danych. To nie działa, nawet jeśli dodam opcje z CreateNewDatabase = true – Peter

1

Chciałem zbudować i opublikować bazę danych na podstawie pliku sqlproj i zapisać przydatne informacje do konsoli. Oto, do czego przybyłem:

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

To jest dla .NET 4 i nowszych. Należy się upewnić, że dołączono odniesienia do zestawu: Microsoft.Build i Microsoft.Build.Framework.