【问题标题】:Using Microsoft.Build.Evaluation to publish a database project (.sqlproj)使用 Microsoft.Build.Evaluation 发布数据库项目 (.sqlproj)
【发布时间】:2012-05-03 19:40:57
【问题描述】:

我需要能够以编程方式发布 SSDT 项目。我正在考虑使用 Microsoft.Build 来执行此操作,但找不到任何文档。创建 .dacpac 似乎很简单,但我将如何发布到现有数据库或至少发布到 .sql 文件。这个想法是让它做当我右键单击项目并选择发布时所做的事情。它应该与选定的数据库进行比较并生成升级脚本。

这是我迄今为止创建的 .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 Example 显示的内容,但在代码中。

抱歉,这就是我的全部。 Build 类的文档很差。任何帮助将不胜感激。

谢谢。

【问题讨论】:

    标签: c# visual-studio-2010 msbuild msbuild-propertygroup sql-server-data-tools


    【解决方案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);
                }
            }
        }
    

    这似乎适用于 2005 年及更高版本的所有 SQL Server 版本。 Microsoft.SqlServer.Management.Dac 中有一组类似的对象可用,但是我相信这是在 DACFx 的先前版本中,并且不包含在最新版本中。因此,请尽可能使用最新版本。

    【讨论】:

    • 太棒了,使用 DACPAC 程序集让我可以完全控制部署。对集成测试也很有用!
    • 最后,一个明智的答案!谢谢 - 只是想补充一点,您需要从Microsoft Visual Studio ??.0\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\120 复制/引用sqlserver.dac.dll - 效果非常好,正是我需要的,如此简单和快速。这应该被接受!
    • 任何将标志“upgradeExisting”设置为 false 的经验?我收到一个异常,告诉我“禁用升级时无法部署到现有数据库”。但我希望 DacServices 先删除数据库。它不起作用,即使我使用 CreateNewDatabase = true 添加选项
    • @Peter - upgradeExisting 过载:services.Deploy(package, connectionString, upgradeExisting: true);
    【解决方案2】:

    我们需要一种方法来告诉 msbuild 如何以及在哪里发布。在 Visual Studio 中打开您的项目并开始 Publish 它。在对话框中输入所有需要的信息,包括您的数据库连接信息和任何自定义 SQLCMD 变量值。 Save Profile As... 到一个文件,例如北风.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});
    

    这可能需要一段时间,并且可能会卡住。耐心点。 :)

    【讨论】:

    • 我需要同时引用 Microsoft.BuildMicrosoft.Build.Framework 程序集才能使此代码正常工作。
    • 一定要检查Build的返回值是否成功。
    • 要监控构建事件,请使用ConfigurableForwardingLogger 并将BuildEventRedirector 设置为自定义IEventRedirector。您可以通过检查 buildEvent 是否为 BuildErrorEventArgs 来检查错误。
    • 如果你想一直发布到一个数据库,没关系,但 DAC 似乎允许我定位任何服务器或数据库,所以我可以根据需要创建和删除数据库,基于DACPAC。
    【解决方案3】:

    您应该使用SqlPackage.exe 发布您的 dacpac。

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

    除了传递太多参数之外,您还可以将设置保存到 DAC 发布配置文件中(这可以从 Visual Studio 完成)

    【讨论】:

    • should ... 应该是 could :)
    【解决方案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.BuildMicrosoft.Build.Framework 的程序集引用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多