4

I have a SQL Project in Visual Studio 2017 and I'm using SSDT to update my project from a SQL Database, looks like this:

enter image description here

Often the database I'm using as my source is changing(often in small and irrelevant ways), when this occurs I cannot update my project, I get the "commonly" "experienced":

Source schema drift detected. Press Compare to refresh.

However in my case this error is legitimate, I just don't care, I would like to update my target anyways. Is there a way to ignore this message and have Visual Studio update my project irregardless of the schema drift?

4

2 回答 2

3

尽管 Microsoft 声称此问题已在 2020 年 5 月的 Visual Studio 2019 和 16.6 中得到修复,但我今天能够在我的计算机上始终如一地重现该问题 - 所以我在我之后对 Visual Studio 2019 的 SSDT 文件进行了一些挖掘(对于未混淆的程序集)能够可靠地重现“检测到源架构漂移。按比较刷新。” 消息,我相信我发现了问题:


  • 中止比较的决定是由Microsoft.Data.Tools.Schema.Utilities.Sql.SchemaCompare.SchemaCompareController::VerifyParticipantsNotDrifted()

    • SchemaCompareController课程在此程序集中:
      • Common7\IDE\Extensions\Microsoft\SQLDB\DAC\150\Microsoft.Data.Tools.Schema.Sql.dll
    • bool如果在调用该方法时它认为源或目标“漂移”了,则此方法返回一个值。
  • 它通过调用 和 对象来确定ISchemaCompareParticipant::IsStale()这一点SourceTarget

    • 就我而言,我Source是我的*.sqlproj项目。所以 SSDT 认为我的项目“过时”了——但为什么呢?
  • 经过更多的挖掘,我看到 SSDT 使用*.sqlproj*.dacpac文件相同的逻辑进行比较。

    • 这是有道理的:当您进行架构比较时,它实际上会在您的和目录中构建*.sqlproj一个*.dacpac文件。MyProject\bin\DebugMyProject\bin\Release
    • 确定.dacpac文件是否“陈旧”的逻辑是检查两件事:
      1. 如果架构比较配置已更改
        • 在我们的例子中,它肯定没有,所以我们可以消除它。
      2. 如果.dacpac文件本身具有旧的构建日期 - 或者.dacpac根本不存在。
        • 这个逻辑在SchemaCompareParticipantForDacpac.BuildArtifactStale()
  • BuildArtifactStale()方法只获取.dacpac's FileInfo.CreationTimeUtcLastWriteTimeUtcLength属性,并将它们与模式比较开始时拍摄的同一文件属性的快照进行比较。

  • 所以有些东西在比较开始和执行生成脚本(或更新目标)步骤之间修改bin\Debug\MyProject.dacpac文件 - 或者无法产生最新的.dacpac输出。

  • 我承认我无法找出导致我的文件bin\Debug\MyProject.dacpac无法正确重建的原因,但我确实看到了一些新的构建警告(来自静态分析)。在解决了这些构建警告并删除了bin\Debug\MyProject.dacpacbin\Release\MyProject.dacpac文件,然后重新运行架构比较后,架构漂移错误不再出现。

我的预感是 SSDT 的静态分析过程会干扰 dacpac 构建过程或以其他方式使构建无效,从而阻止.dacpac生成最终文件,即使它构建得很好。

在恢复我的更改以恢复静态分析警告后,我无法重现该问题(ARGH!)所以我猜测这是构建过程或静态分析部分中的竞争条件。


TL;博士:

做这 3 件事(你应该不需要重新启动 Visual Studio 或重新加载 SSDT 项目)

  1. 确保您没有任何构建错误或警告,尤其是来自 SSDT 的静态分析工具的任何内容。
  2. 删除您的bin\Debug\YourProject.dacpacbin\Release\YourProject.dapac文件。
  3. 进行项目重建(调试和发布)并检查.dacpac文件上的 Last-Modified 时间戳在比较完成和单击 Generate Scripts 或 Publish 之间没有变化。
    • 如果您确实看到 Last-Modified 时间更改,请查看您是否可以找出导致它的原因并在此 QA 中告知我们,以便我们向 MS 提供可靠的错误报告。
于 2021-03-23T18:39:59.283 回答
2

我解决这个问题的方法是在更新项目之前做一个 SSDT 项目快照,它将保存为 DACPAC。更新项目后,我在 SSDT 项目和 DACPAC 文件之间进行架构比较。这只提取对项目所做的更改。然后,我没有单击模式比较上的更新按钮(如果目标是 DACPAC,这将不起作用),我单击生成脚本按钮。然后我可以针对目标数据库运行生成的脚本。

注意:生成的脚本将使用 DACPAC 文件的名称作为文件头部的数据库名称。在运行脚本之前将其更改为正确的数据库名称。

顺便说一句,如果您忘记在进行更改之前拍摄 SSDT 项目的快照(我偶尔会这样做),只要 SSDT 项目处于源代码控制中,这不是问题。只需提交您的更改,然后在拍摄项目快照之前检查您的更改之前的最后一次提交。然后再次检查您的最新提交,并在更改的 SSDT 项目和保存的快照 DACPAC 之间进行架构比较。

于 2018-06-14T22:21:03.887 回答