将 .sqlproj 迁移到 Sdk 样式会破坏某些数据库选项

Migrating .sqlproj to Sdk style breaks certain database options

我正在尝试将我现有的 .sqlproj 目标 .NET Framework 4.7.2 迁移到新的 Sdk 样式项目,以便我可以使用新的 .NET SDK 生成 .dacpac。我的新 .csproj 看起来像这样:

<Project Sdk="MSBuild.Sdk.SqlProj/1.17.3">
  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <SqlServerVersion>SqlAzure</SqlServerVersion>
    <BundledNETCoreAppTargetFrameworkVersion>5.0</BundledNETCoreAppTargetFrameworkVersion>
  </PropertyGroup>

  <PropertyGroup>
    <SchemaVersion>2.0</SchemaVersion>

    <CompatibilityMode>130</CompatibilityMode>
    <AnsiNullDefault>False</AnsiNullDefault>
    <AnsiPadding>False</AnsiPadding>
    <AnsiWarnings>False</AnsiWarnings>
    <ArithAbort>False</ArithAbort>
    <ConcatNullYieldsNull>False</ConcatNullYieldsNull>
    <NumericRoundAbort>False</NumericRoundAbort>
    <RecursiveTriggersEnabled>False</RecursiveTriggersEnabled>
.......................
  </PropertyGroup>

第二个 PropertyGroup 是旧 .sqlproj 相同元素的 99% 副本 - 我想确保新 .dacpac 与旧元素相同。问题是新 .csproj 不考虑一些配置参数。如果我使用 SqlPackage 实用程序针对同一个数据库从新的 .dacpac 生成脚本,它包含旧脚本中不存在的以下内容:

IF EXISTS (SELECT 1
           FROM   [sys].[databases]
           WHERE  [name] = N'$(DatabaseName)')
    BEGIN
        ALTER DATABASE [$(DatabaseName)]
            SET ANSI_PADDING ON,
                ANSI_WARNINGS ON,
                ARITHABORT ON,
                QUOTED_IDENTIFIER ON,
                ANSI_NULL_DEFAULT ON 
            WITH ROLLBACK IMMEDIATE;
    END

换句话说,AnsiPaddingAnsiWarnings 等参数以及其他一些参数将被忽略。此外,我不得不评论其他一些导致构建失败的参数,例如 DbScopedConfigLegacyCardinalityEstimation:

System.ArgumentException: Unable to parse value for property with name DbScopedConfigLegacyCardinalityEstimation: Off (Parameter 'value')

为什么会发生这种情况,我该如何解决?我需要确保切换到 Sdk 样式项目不会破坏我的数据库,这将在生产中造成灾难。

显然他们重命名了很多东西。因此,如果您想将 .sqlproj 迁移到新的 Sdk 样式 .csproj,您需要小心。 AnsiPadding 现在是 AnsiPaddingOnAnsiWarningsAnsiWarningsOn,等等

<AnsiPaddingOn>False</AnsiPaddingOn>
<AnsiWarningsOn>False</AnsiWarningsOn>
<ArithAbortOn>False</ArithAbortOn>

一些non-boolean参数也改变了。例如:

<TargetRecoveryTimeUnit>SECONDS</TargetRecoveryTimeUnit>`

现在需要(注意大小写,见Time Unit enum

<TargetRecoveryTimeUnit>Seconds</TargetRecoveryTimeUnit>

查看官方Microsoft.SqlServer.Dac.Model documentation,始终验证生成的脚本。我已经成功迁移了我的项目,现在使用从新 .csproj 构建的 .dacpac 来应用我的迁移。

接受的答案修复了 OP 的问题,因为它强制项目中的设置与数据库匹配。另一种防止生成 ALTER DATABASE 语句的方法是包含一个 属性,指示忽略所有数据库选项。

    <PropertyGroup>
        <ScriptDatabaseOptions>False</ScriptDatabaseOptions>
    </PropertyGroup>

顺便说一句,这个问题与 this one 重复。