忽略 "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
值,如果它认为源或目标在调用该方法时被“漂移”。
它通过在 Source
和 Target
对象上调用 ISchemaCompareParticipant::IsStale()
来确定这一点。
- 就我而言,我的
Source
是我的 *.sqlproj
项目。所以 SSDT 认为我的项目“过时”了 - 但为什么呢?
经过更多挖掘,我发现 SSDT 使用与 *.dacpac
文件相同的逻辑来比较 *.sqlproj
。
- 这是有道理的:因为当您进行架构比较时,它实际上会将您的
*.sqlproj
构建到 MyProject\bin\Debug
和 MyProject\bin\Release
目录中的 *.dacpac
文件。
- 确定
.dacpac
文件是否“陈旧”的逻辑是检查两件事:
- 如果架构比较配置已更改
- 在我们的例子中,它肯定没有,所以我们可以消除它。
- 如果
.dacpac
文件本身有旧的构建日期 - 或者如果 .dacpac
根本不存在。
- 这个逻辑在
SchemaCompareParticipantForDacpac.BuildArtifactStale()
BuildArtifactStale()
方法只是获取 .dacpac
的 FileInfo.CreationTimeUtc
、LastWriteTimeUtc
和 Length
属性并将它们与启动架构比较时拍摄的同一文件属性的快照。
所以某事正在比较开始和执行生成脚本(或更新目标)之间修改bin\Debug\MyProject.dacpac
文件步骤 - 或无法生成最新的 .dacpac
输出。
我承认我无法找出是什么 东西 导致我的 bin\Debug\MyProject.dacpac
文件无法正确重建,但我确实看到了一些新的构建警告(来自静态分析)。在解决这些构建警告并删除 bin\Debug\MyProject.dacpac
和 bin\Release\MyProject.dacpac
文件,然后重新 运行 架构比较后,架构漂移错误不再出现。
我的直觉是 SSDT 的静态分析过程会干扰 dacpac 构建过程或以其他方式使构建无效,从而阻止生成最终的 .dacpac
文件,即使它构建良好。
恢复我的更改以恢复静态分析警告后,我无法重现问题(哎呀!)所以我猜这是构建过程或静态分析部分中的竞争条件。
TL;DR:
做这 3 件事(您应该不需要重新启动 Visual Studio 或重新加载 SSDT 项目)
- 确保您没有任何构建错误或警告,尤其是来自 SSDT 的静态分析工具。
- 删除您的
bin\Debug\YourProject.dacpac
和 bin\Release\YourProject.dapac
文件。
- 重建项目(调试和发布)并检查
.dacpac
文件上的 Last-Modified 时间戳在比较完成和您单击“生成脚本”或“发布”之间没有变化。
- 如果您确实看到 Last-Modified 时间发生变化,看看您是否能找出导致它的原因并在本次 QA 中告知我们,以便我们向 MS 提供可靠的错误报告。
我在 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
值,如果它认为源或目标在调用该方法时被“漂移”。
它通过在
Source
和Target
对象上调用ISchemaCompareParticipant::IsStale()
来确定这一点。- 就我而言,我的
Source
是我的*.sqlproj
项目。所以 SSDT 认为我的项目“过时”了 - 但为什么呢?
- 就我而言,我的
经过更多挖掘,我发现 SSDT 使用与
*.dacpac
文件相同的逻辑来比较*.sqlproj
。- 这是有道理的:因为当您进行架构比较时,它实际上会将您的
*.sqlproj
构建到MyProject\bin\Debug
和MyProject\bin\Release
目录中的*.dacpac
文件。 - 确定
.dacpac
文件是否“陈旧”的逻辑是检查两件事:- 如果架构比较配置已更改
- 在我们的例子中,它肯定没有,所以我们可以消除它。
- 如果
.dacpac
文件本身有旧的构建日期 - 或者如果.dacpac
根本不存在。- 这个逻辑在
SchemaCompareParticipantForDacpac.BuildArtifactStale()
- 这个逻辑在
- 如果架构比较配置已更改
- 这是有道理的:因为当您进行架构比较时,它实际上会将您的
BuildArtifactStale()
方法只是获取.dacpac
的FileInfo.CreationTimeUtc
、LastWriteTimeUtc
和Length
属性并将它们与启动架构比较时拍摄的同一文件属性的快照。所以某事正在比较开始和执行生成脚本(或更新目标)之间修改
bin\Debug\MyProject.dacpac
文件步骤 - 或无法生成最新的.dacpac
输出。我承认我无法找出是什么 东西 导致我的
bin\Debug\MyProject.dacpac
文件无法正确重建,但我确实看到了一些新的构建警告(来自静态分析)。在解决这些构建警告并删除bin\Debug\MyProject.dacpac
和bin\Release\MyProject.dacpac
文件,然后重新 运行 架构比较后,架构漂移错误不再出现。
我的直觉是 SSDT 的静态分析过程会干扰 dacpac 构建过程或以其他方式使构建无效,从而阻止生成最终的 .dacpac
文件,即使它构建良好。
恢复我的更改以恢复静态分析警告后,我无法重现问题(哎呀!)所以我猜这是构建过程或静态分析部分中的竞争条件。
TL;DR:
做这 3 件事(您应该不需要重新启动 Visual Studio 或重新加载 SSDT 项目)
- 确保您没有任何构建错误或警告,尤其是来自 SSDT 的静态分析工具。
- 删除您的
bin\Debug\YourProject.dacpac
和bin\Release\YourProject.dapac
文件。 - 重建项目(调试和发布)并检查
.dacpac
文件上的 Last-Modified 时间戳在比较完成和您单击“生成脚本”或“发布”之间没有变化。- 如果您确实看到 Last-Modified 时间发生变化,看看您是否能找出导致它的原因并在本次 QA 中告知我们,以便我们向 MS 提供可靠的错误报告。