DacServices.Deploy到SQL Server LocalDB 2016失败 - 无法连接

cri*_*mbo 5 dac localdb sql-server-data-tools sql-server-2016-localdb

此调用DacServices.Deploy一直适用于SQL Server LocalDB 2014,但在安装SQL Server LocalDB 2016时失败:

string dacConnectionString = $"Server=(localdb)\\mssqllocaldb; Integrated Security=true; database={DatabaseName}";
var dacServices = new DacServices(dacConnectionString);
dacServices.Message += (sender, args) => Console.WriteLine($"{args.Message.Prefix}: {args.Message.Message}"); // Log dacpac deploy messages
dacServices.Deploy(LoadDacPac(), DatabaseName, true, new DacDeployOptions()
                                                     {
                                                         BlockOnPossibleDataLoss = false
                                                     });
Run Code Online (Sandbox Code Playgroud)

DacServices.DeployLocalDB 2016 抛出的异常是:

Microsoft.SqlServer.Dac.DacServicesException was unhandled by user code
  HResult=-2146233088
  Message=Could not deploy package.
  Source=Microsoft.SqlServer.Dac
  StackTrace:
       at Microsoft.SqlServer.Dac.DeployOperation.Microsoft.SqlServer.Dac.IOperation.Run(OperationContext context)
       at Microsoft.SqlServer.Dac.OperationExtension.Execute(IOperation operation, DacLoggingContext loggingContext, CancellationToken cancellationToken)
       at Microsoft.SqlServer.Dac.DacServices.InternalDeploy(IPackageSource packageSource, Boolean isDacpac, String targetDatabaseName, DacDeployOptions options, CancellationToken cancellationToken, DacLoggingContext loggingContext)
       at Microsoft.SqlServer.Dac.DacServices.Deploy(DacPackage package, String targetDatabaseName, Boolean upgradeExisting, DacDeployOptions options, Nullable`1 cancellationToken)
       at Tv.Base.Test.Database.TestSqlLocalDb.CreateOrUpdateDatabaseIfNeeded(Boolean force) in D:\BuildAgent-02\work\6ec37398501798d0\src\Base.Test.Database\TestSqlLocalDb.cs:line 173
       at Tv.Services.Inventory.DataAccess.Tests.InventoryDatabaseFixture..ctor() in C:\src\tv\services\inventory\test\DataAccess.Tests\InventoryDatabaseFixture.cs:line 40
  InnerException: 
       HResult=-2146233088
       Message=Unable to connect to target server.
       Source=Microsoft.Data.Tools.Schema.Sql
       StackTrace:
            at Microsoft.Data.Tools.Schema.Sql.Deployment.SqlDeploymentEndpointServer.OnInit(ErrorManager errors, String targetDBName)
            at Microsoft.Data.Tools.Schema.Sql.Deployment.SqlDeployment..ctor(SqlDeploymentConstructor constructor)
            at Microsoft.Data.Tools.Schema.Sql.Deployment.SqlDeploymentConstructor.ConstructServiceImplementation()
            at Microsoft.SqlServer.Dac.DacServices.CreatePackageToDatabaseDeployment(String connectionString, IPackageSource packageSource, String targetDatabaseName, DacDeployOptions options, ErrorManager errorManager)
            at Microsoft.SqlServer.Dac.DeployOperation.<>c__DisplayClass3.<>c__DisplayClass5.<CreatePlanInitializationOperation>b__1()
            at Microsoft.Data.Tools.Schema.Sql.Dac.OperationLogger.Capture(Action action)
            at Microsoft.SqlServer.Dac.DeployOperation.<>c__DisplayClass3.<CreatePlanInitializationOperation>b__0(Object operation, CancellationToken token)
            at Microsoft.SqlServer.Dac.Operation.Microsoft.SqlServer.Dac.IOperation.Run(OperationContext context)
            at Microsoft.SqlServer.Dac.ReportMessageOperation.Microsoft.SqlServer.Dac.IOperation.Run(OperationContext context)
            at Microsoft.SqlServer.Dac.OperationExtension.CompositeOperation.Microsoft.SqlServer.Dac.IOperation.Run(OperationContext context)
            at Microsoft.SqlServer.Dac.OperationExtension.CompositeOperation.Microsoft.SqlServer.Dac.IOperation.Run(OperationContext context)
            at Microsoft.SqlServer.Dac.DeployOperation.Microsoft.SqlServer.Dac.IOperation.Run(OperationContext context)
Run Code Online (Sandbox Code Playgroud)

"无法连接"错误似乎不正确/可能会掩盖真正的错误,因为指定的连接字符串允许我使用连接到数据库SqlConnection,因为我可以使用命令行将此dacpac部署到SQL Server LocalDB 2016:

sqlpackage "/Action:publish" "/SourceFile:MyDatabase.dacpac" "/TargetConnectionString:Server=(localdb)\mssqllocaldb;Database=MyDatabase;Integrated Security=true"
Run Code Online (Sandbox Code Playgroud)

有关我的设置的更多信息:

> sqllocaldb info mssqllocaldb
Name:               MSSQLLocalDB
Version:            13.0.1601.5
Shared name:
Owner:              DOMAIN\user
Auto-create:        Yes
State:              Running
Last start time:    7/1/2016 5:09:43 PM
Instance pipe name: np:\\.\pipe\LOCALDB#C1DD8548\tsql\query

> sqllocaldb v
Microsoft SQL Server 2014 (12.0.2000.8)
Microsoft SQL Server 2016 (13.0.1601.5)
Run Code Online (Sandbox Code Playgroud)

Microsoft.SqlServer.Dac正在使用的程序集来自这个NuGet包:https: //www.nuget.org/packages/Microsoft.SqlServer.Dac

cri*_*mbo 8

对此的修复确实是为了更新Microsoft.SqlServer.Dac我们正在使用的程序集的版本- 我发现我应该在看到@ kevin-cunnane的建议之前不久尝试.

有一些因素使得这不太明显,这就是它在SO上的原因:

  1. Dac的错误消息"无法连接到目标服务器"并不表示版本不兼容.然而,从互联网上寻找(例如DACPAC将不会部署,因为'无法连接到服务器'?)似乎此错误消息可能意味着版本不兼容,此外还有错误的连接字符串,防火墙问题等.
  2. 发布了几个包含Microsoft.SqlServer.Dac相关程序集的NuGet包.其中一些不是由Microsoft维护的,包括我使用的那个(Microsoft.SqlServer.Dac).微软官方版本直到2016年6月才在NuGet.org上发布,它没有最明显的NuGet id(Microsoft.SqlServer.DacFx.x64).所以跑步update-package Microsoft.SqlServer.Dac没有达到预期的效果.
  3. "官方"NuGet包未在MSDN + DAC页面的任何位置列出 - 您可以在此处提及:https://msdn.microsoft.com/en-us/library/dn702988%28v = sql. 120%29.aspx - 但事实并非如此.
  4. Visual Studio 2016安装SQL LocalDB 2016,它确实包含正确的Dac程序集(C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\130\Microsoft.SqlServer.Dac.dll),但它们未安装在GAC中或者很容易找到.

有效的修复方法是

# Remove the old NuGet dependencies
uninstall-package Microsoft.SqlServer.Dac

# Install the new Dac NuGet package
Install-Package Microsoft.SqlServer.DacFx.x64
Run Code Online (Sandbox Code Playgroud)

如果您碰巧看到Dac团队的请求:

  • 请从MSDN文档链接到正确的NuGet包
  • 请改进错误消息以指示需要更新的客户端软件
  • 请求其他NuGet软件包维护人员注意官方NuGet软件包的存在,或提供引用官方NuGet软件包的升级,b/c多个软件包的存在可能会引起焦虑.

(顺便说一下,尽管这里有困难,Dac/SSDT还是很棒.我还没有看到任何可比的开发工具适用于任何竞争关系数据库.)