Использование Microsoft.Build.Evaluation для публикации проекта базы данных (.sqlproj)
Мне нужно иметь возможность публиковать проект SSDT программно. Я использую Microsoft.Build для этого, но не могу найти никакой документации. Кажется довольно простым создать .dacpac, но как я могу либо опубликовать существующую базу данных, либо, по крайней мере, в файл .sql. Идея состоит в том, чтобы заставить ее делать то, что она делает, когда я нажимаю правой кнопкой мыши на проекте и выбираю публикацию. Он должен сравниваться с выбранной базой данных и генерировать обновление script.
Это то, что я до сих пор создавал .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());
}
}
По существу, я пытаюсь сделать то, что показывает этот пример MSBuild, но в коде.
Извините, что это все, что у меня есть. Докетирование по классам Build очень плохое. Любая помощь будет оценена.
Спасибо.
Ответы
Ответ 1
Мне пришлось сделать что-то подобное, потому что VSDBCMD, который мы ранее использовали, не развертывается в SQL Server 2012, и нам нужно его поддерживать. Я обнаружил сборку Microsoft.SqlServer.Dac, которая, как представляется, входит в инструменты данных SQL Server (http://msdn.microsoft.com/en-us/data/tools.aspx)
Когда вы запустите это на клиентском компьютере, вам понадобится полная версия инфраструктуры .NET 4, а также типы SQL CLR и пакет SQL T-SQL ScriptDOM, найденный здесь: http://www.microsoft.com/en-us/download/details.aspx?id=29065
Ниже приведен код из макета, который я сделал для тестирования нового метода развертывания, и разворачивает данный файл .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);
}
}
}
Это похоже на работу со всеми версиями SQL Server с 2005 года и выше. Существует аналогичный набор объектов, доступных в Microsoft.SqlServer.Management.Dac, однако я считаю, что это в предыдущей версии DACFx и не входит в последнюю версию. Поэтому используйте последнюю версию, если сможете.
Ответ 2
Нам нужен способ сообщить msbuild, как и где публиковать. Откройте проект в Visual Studio и начните с Publish
его. Введите всю необходимую информацию в диалоговом окне, включая информацию о подключении к БД и любые значения переменных SQLCMD. Save Profile As...
в файл, например. Northwind.publish.xml. (Вы можете затем Cancel
.) Теперь мы можем использовать это и файл проекта для создания и публикации:
// 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});
Это может занять некоторое время и может показаться застрявшим. Потерпи.:)
Ответ 3
Вы должны использовать SqlPackage.exe для публикации своего dacpac.
SqlPackage.exe
/Action:Publish
/SourceFile:C:/file.dacpac
/TargetConnectionString:[Connection string]
Вместо того, чтобы передавать слишком много параметров, вы можете сохранить свои настройки в DAC Publish Profile (это можно сделать из visual studio)
Ответ 4
Я хотел создать и опубликовать базу данных на основе файла sqlproj и записать полезную информацию на консоль. Вот, к чему я пришел:
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; }
}
Это для .NET 4 и выше. Обязательно укажите ссылки на Microsoft.Build и Microsoft.Build.Framework.