忽略 "Source schema drift detected" 错误,继续更新

Ignore "Source schema drift detected" Error, Continue With Update

我在 Visual Studio 2017 年有一个 SQL 项目,我正在使用 SSDT 从 SQL 数据库更新我的项目,如下所示:

我用作源的数据库经常发生变化(通常以小而无关的方式),发生这种情况时我无法更新我的项目,我得到“commonly" "experienced”:

Source schema drift detected. Press Compare to refresh.

但是在我的情况下这个错误是合理的,我不在乎,无论如何我都想更新我的目标。有没有办法忽略此消息并让 Visual Studio 更新我的项目而不考虑架构漂移?

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

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

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

Despite Microsoft claiming this issue was fixed in Visual Studio 2019, 16.6 back in May 2020,我今天能够在我的计算机上始终如一地重现该问题 - 所以在我能够可靠地解决问题之后,我对 Visual Studio 2019 年的 SSDT 文件(是的,对于未混淆的程序集)进行了一些挖掘重现“检测到源模式漂移。按比较刷新。”消息,我相信我发现了问题:


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

    做出的
    • SchemaCompareController class 在此程序集中:
      • Common7\IDE\Extensions\Microsoft\SQLDB\DAC0\Microsoft.Data.Tools.Schema.Sql.dll
    • 此方法 returns 一个 bool 值,如果它认为源或目标在调用该方法时被“漂移”。
  • 它通过在 SourceTarget 对象上调用 ISchemaCompareParticipant::IsStale() 来确定这一点。

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

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

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

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

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

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


TL;DR:

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

  1. 确保您没有任何构建错误或警告,尤其是来自 SSDT 的静态分析工具。
  2. 删除您的 bin\Debug\YourProject.dacpacbin\Release\YourProject.dapac 文件。
  3. 重建项目(调试和发布)并检查 .dacpac 文件上的 Last-Modified 时间戳在比较完成和您单击“生成脚本”或“发布”之间没有变化。
    • 如果您确实看到 Last-Modified 时间发生变化,看看您是否能找出导致它的原因并在本次 QA 中告知我们,以便我们向 MS 提供可靠的错误报告。