DacFx 回归错误 v14 与 v15版本 15 在 DacServices.Deploy() 时发出“ALTER DATABASE”语句,但不应该

问题描述

我在 Web 项目中使用 DACFx DLL,该项目可以生成 dacpac 并将其恢复到其他地方(另一台服务器中的新空数据库,可能还有不同的 sql Server 版本)。

通过 DacServices.Extract() 创建的备份版本为 14(例如 14.0.3917.1)或版本 15(例如 15.0.5084.2)可以通过 DacServices.Deploy() 恢复,没有任何问题。

在还原时引用 15.0.5084.2 而不是 14.0.3917.1 的完全相同的代码 (c# .csproj) 失败,错误类似于以下内容

Error sql72014: .Net sqlClient Data Provider: Msg 5170,Level 16,State 1,Line 1 Cannot create file 'X:\sqlServer\DATA\olddb.ldf' because it already exists. Change the file path or the file name,and retry the operation.
Error sql72045: Script execution error. The executed script: ALTER DATABASE [$(DatabaseName)] ADD LOG FILE (NAME = [dnn9me_log],FILENAME = 'X:\sqlServer\DATA\olddb.ldf',SIZE = 2880 KB,MAXSIZE = 2097152 MB,FILEGROWTH = 10 %);

sql Server 2014 或更高版本的数据库(例如 2019)上运行 Extract() 和 Deploy() 的结果相同。 我的意思是,一个标准的简单数据库不在 Azure 上。

我使用以下选项来执行 Extract():

DacExtractOptions = 
{
ExtractAllTableData = true,IgnorePermissions = true,IgnoreUserLoginMappings = true,ExtractUsageProperties = false,IgnoreExtendedProperties = false,ExtractReferencedServerScopedElements = false,ExtractApplicationScopedobjectsOnly = false,}

我使用以下选项来执行 Deploy():


excludeObjectTypes = ServerAuditSpecifications,ServerRoleMembership,ServerRoles,ServerTriggers,LinkedServers,Filegroups,Logins,Users,Assemblies,AssemblyFiles,ApplicationRoles,Permissions,RoleMembership,DatabaSEOptions,DatabaseRoles,DatabaseTriggers,PartitionSchemes,ExtendedProperties,Tables,Views,UserDefinedDataTypes,UserDefinedTableTypes,ScalarValuedFunctions,TableValuedFunctions,PartitionFunctions,StoredProcedures,XmlSchemaCollections

doNotDropObjectTypes =  ServerAuditSpecifications,LinkedServerLogins,XmlSchemaCollections


DacDeployOptions = 
{
IgnorePermissions = true,IgnoreUserSettingsObjects =  true,IgnoreLoginSids = true,IgnoreRoleMembership =  false,DoNotDropObjectTypes = doNotDropObjectTypes.ToArray(),ExcludeObjectTypes = excludeObjectTypes.ToArray(),AllowDropBlockingAssemblies = false,AllowIncompatiblePlatform = true,AllowUnsafeRowLevelSecurityDataMovement = false,BackupDatabaseBeforeChanges = false,BlockOnPossibleDataLoss = true,BlockWhenDriftDetected = true,CommentOutSetvarDeclarations = false,CompareUsingTargetCollation = false,CreateNewDatabase = false,DeployDatabaseInSingleusermode = false,disableAndReenableDdlTriggers = true,DoNotAlterChangeDataCaptureObjects = true,DoNotAlterReplicatedobjects = true,RegisterDataTierApplication = false,DropConstraintsnotinSource = true,DropDmlTriggersnotinSource = true,DropExtendedPropertiesnotinSource = true,DropIndexesnotinSource = true,DropObjectsnotinSource = false,DropPermissionsnotinSource = false,DropRoleMembersnotinSource = false,DropStatisticsnotinSource = false,GenerateSmartDefaults = false,IgnoreAnsiNulls = false,IgnoreAuthorizer = false,IgnoreColumnCollation = false,IgnoreComments = false,IgnoreCryptographicProviderFilePath = true,IgnoreDdlTriggerOrder = false,IgnoreDdlTriggerState = false,IgnoreDefaultSchema = false,IgnoreFileAndLogFilePath = true,IgnoreDmlTriggerOrder = false,IgnoreDmlTriggerState = false,IgnoreFileSize = true,IgnoreFilegroupPlacement = true,IgnoreFillFactor = true,IgnoreFullTextCatalogFilePath = true,IgnoreIdentitySeed = false,IgnoreIncrement = false,IgnoreIndexOptions = false,IgnoreIndexPadding = true,IgnoreKeywordCasing = true,IgnoreLockHintsOnIndexes = false,IgnoreNotForReplication = false,IgnoreObjectPlacementOnPartitionScheme = true,IgnorePartitionSchemes = false,IgnoreQuotedIdentifiers = false,IgnoreRouteLifetime = true,IgnoreSemicolonBetweenStatements = true,IgnoreTableOptions = false,IgnoreWhitespace = true,IgnoreWithNocheckOnCheckConstraints = false,IgnoreWithNocheckOnForeignKeys = false,IncludeCompositeObjects = false,IncludeTransactionalScripts = false,NoAlterStatementstochangeClrTypes = false,PopulateFilesOnFileGroups = false,RunDeploymentPlanExecutors = false,ScriptDatabaseCollation = false,ScriptDatabaseCompatibility = false,ScriptDatabaSEOptions = true,ScriptDeployStateChecks = true,ScriptFileSize = false,ScriptNewConstraintValidation = true,ScriptRefreshModule = true,TreatVerificationErrorsAsWarnings = true,UnmodifiableObjectWarnings = false,VerifyCollationCompatibility = true,IgnoreColumnorder = true,}

如何防止在发出 Extract() 时创建这些 ALTER DATABASE 语句和/或在发出 Deploy() 时如何防止它们被执行?

作为一种解决方法,我考虑使用 Contributor (example contributors) 来识别任何 ALTER DATABASE 并阻止它运行。

问题是,我无法让应用程序看到 contributor,它是同一个 csproj 中的一个类。

也许贡献者仅在使用 sqlPackage.exe 并且定义贡献者的 DLL 放置在应用程序的 \bin 文件夹之外的特定位置时才起作用。 这是真的? 或者有一种方法可以让贡献者在我的情况下工作(网络应用程序只能在其 \bin 文件夹中看到 DLL)。

解决方法

要获取特定部署/发布操作的脚本,请执行以下任一操作:

  • 使用 SqlPackage 的快捷方式 /a:Script
  • 使用 DacServices.GenerateCreateScript