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

6

这个调用 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
                                                     });

DacServices.Deploy 在 LocalDB 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)

“无法连接”错误似乎是错误的/可能会掩盖真正的错误,这是因为指定的连接字符串允许我使用SqlConnection连接到数据库,并且因为我可以使用命令行将此dacpac部署到SQL Server LocalDB 2016:
sqlpackage "/Action:publish" "/SourceFile:MyDatabase.dacpac" "/TargetConnectionString:Server=(localdb)\mssqllocaldb;Database=MyDatabase;Integrated Security=true"

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

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

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


它以何种方式失败? - Ed Elliott
抱歉 - 我不小心在写完问题之前提交了它 - 添加新标签导致了这个问题。 - crimbo
1
酷,"sqllocaldb info mssqllocaldb"和"sqllocaldb v"是做什么用的? - Ed Elliott
连接字符串中的"{DatabaseName}"只是针对堆栈溢出吗?如果打印连接字符串,它是否正确? - Ed Elliott
2
你使用的DLL版本是什么?你需要v13 DLL(现在可以通过nuget获取:https://www.nuget.org/packages/Microsoft.SqlServer.DacFx.x64/)来针对SQL Server 2016服务器。很可能你仍然绑定到v12 DLL。 - Kevin Cunnane
显示剩余4条评论
1个回答

9
解决这个问题的方法是更新我们使用的Microsoft.SqlServer.Dac程序集的版本 - 在看到@kevin-cunnane的建议之前,我已经发现应该尝试更新它了。
这个问题不是很明显有几个因素造成了这个问题,这就是为什么会出现在SO上的原因:
1. Dac的错误信息“无法连接到目标服务器”并没有以任何方式表明版本不兼容。但是从浏览互联网(例如DACPAC无法部署因为'无法连接到服务器'?)中,似乎此错误消息可以意味着除了不正确的连接字符串、防火墙问题等之外还可能意味着版本不兼容。 2. 有几个NuGet包发布了包含Microsoft.SqlServer.Dac和相关程序集的内容。其中一些不是由Microsoft维护的,包括我正在使用的一个(Microsoft.SqlServer.Dac)。官方的Microsoft发布的版本直到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

如果 Dac 团队看到这条请求:

  • 请在 MSDN 文档中链接正确的 NuGet 包。
  • 请改进错误信息以指出需要新的客户端软件。
  • 请请求其他 NuGet 包维护者注意官方 NuGet 包的存在,或提供引用官方 NuGet 包的升级版本,因为多个包的存在可能会引起烦恼。

顺便说一下,尽管存在困难,但 Dac/SSDT 是令人惊叹的。对于任何竞争性关系型数据库,我都没有看到过任何可比较的开发工具。


1
谢谢Crimbo,我们会考虑更新文档。有一个问题 - 非官方的Dac nuget是许多人使用的东西。删除它不会影响/破坏他们吗?这就是我们没有推动完成此事的原因。我们正在努力平衡提供官方支持和避免对现有用户产生负面影响之间的关系。 - Kevin Cunnane
你说得对,Kevin。撤下它会太过分了。我会删除那个建议。其他选项怎么样?比如要求作者部署一个新的NuGet包,该包为空,具有正确的版本号(13.0),但依赖于正确的NuGet包?或者至少在他们的NuGet页面上加上一条注释。 - crimbo
我们可以询问这个问题 - 我们已经联系了他们,他们很乐意帮助我们获得官方版本的良好支持。 - Kevin Cunnane
我必须承认,SSDT 彻底改变了我们的开发流程,使其变得更好。 - BozoJoe
1
谢谢Crimbo!!! 我在Azure SQL数据库中遇到了同样的问题,显然在我们的管理软件中更改dacpac版本解决了这个问题。首先我向Azure团队提出了问题,在那里我被重定向到SQL团队,然后被要求使用ssms部署,最后你的回答起了魔法。在修复此问题上浪费了很多精力和时间。如果错误消息能得到修复,那将真正有帮助。 - Hari Priya Thangavel
@KevinCunnane - 几年后,在NuGet中搜索“ssdt”并没有显示任何相关的软件包。这部分是由于NuGet的搜索和排序不佳,但另一部分则是由于软件包的命名选择和缺乏“SSDT”标签。这使得很难找到这个(以及报表查看器)软件包,这是一个巨大的不公。 - StingyJack

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接