microsoft / microsoft/DacFx

SchemaComparison reports comment differences that PublishChangesToProject silently ignores — header comments above CREATE never sync to project files

Open
#817 0 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
C#
Stars
460
Forks
29
Avg merge
4d 9h
Merged PRs (30d)
7

Description

- DacFx 162.3.566
- .NET 8, Windows 11
- Environment (local platform and source/target platforms):

`SchemaComparison.Compare()` detects differences that exist only in comments (including the conventional header comment block above `CREATE PROCEDURE`), but `SchemaComparisonResult.PublishChangesToProject()` generates an empty update plan for them and still reports `Success = true` with zero changed files. Additionally, even when a module has a *real* body change, the file update rewrites only the statement body — the header comment above `CREATE` in the project file is never updated from the source.

The two layers disagree about what an object is: the comparison layer diffs the full source text (header included), while the update planner works on the semantic model where the header lives only in the `SysCommentsObjectAnnotation` (`HeaderContents`, `CreateOffset`) and is not actionable. The result is differences that are shown to the user but can never be applied.

dacpac→database carries headers along with real changes, while database→project never does.

**Steps to Reproduce:**

```powershell
# point $dac at the DacFx payload (sqlpackage dotnet tool shown; NuGet lib/ works too)
$dac = "$env:USERPROFILE\.dotnet\tools\.store\microsoft.sqlpackage\162.3.566\microsoft.sqlpackage\162.3.566\tools\net8.0\any"
Add-Type -Path "$dac\runtimes\win\lib\net6.0\Microsoft.Data.SqlClient.dll"
Add-Type -Path "$dac\Microsoft.SqlServer.TransactSql.ScriptDom.dll"
Add-Type -Path "$dac\Microsoft.SqlServer.Dac.dll"
Add-Type -Path "$dac\Microsoft.SqlServer.Dac.Extensions.dll"

$work = Join-Path $env:TEMP 'dacfx-comment-repro'
Remove-Item $work -Recurse -Force -ErrorAction SilentlyContinue
New-Item -ItemType Directory "$work\proj\dbo\StoredProcedures" -Force | Out-Null

function Build-Dacpac([string]$path, [string]$sql) {
$model = [Microsoft.SqlServer.Dac.Model.TSqlModel]::new(
[Microsoft.SqlServer.Dac.Model.SqlServerVersion]::Sql150,
[Microsoft.SqlServer.Dac.Model.TSqlModelOptions]::new())
$model.AddObjects($sql)
$meta = [Microsoft.SqlServer.Dac.PackageMetadata]::new()
$meta.Name = 'Repro'; $meta.Version = '1.0.0.0'
[Microsoft.SqlServer.Dac.DacPackageExtensions]::BuildPackage($path, $model, $meta,
[Microsoft.SqlServer.Dac.PackageOptions]::new())
$model.Dispose()
}

# target project file: header ONE; source: header TWO — the ONLY difference is the header comment
$fileV = "-- header ONE`r`nCREATE PROCEDURE [dbo].[T]`r`nAS`r`nBEGIN`r`n SELECT 1 AS V`r`nEND"
$dbV = "-- header TWO`r`nCREATE PROCEDURE [dbo].[T]`r`nAS`r`nBEGIN`r`n SELECT 1 AS V`r`nEND"

Build-Dacpac "$work\source.dacpac" $dbV
[System.IO.File]::WriteAllText("$work\proj\dbo\StoredProcedures\T.sql", $fileV)
[System.IO.File]::WriteAllText("$work\proj\P.sqlproj",
'PMicrosoft.Data.Tools.Schema.Sql.Sql150DatabaseSchemaProvider')

$cmp = [Microsoft.SqlServer.Dac.Compare.SchemaComparison]::new(
[Microsoft.SqlServer.Dac.Compare.SchemaCompareDacpacEndpoint]::new("$work\source.dacpac"),
[Microsoft.SqlServer.Dac.Compare.SchemaCompareProjectEndpoint]::new(
"$work\proj\P.sqlproj", [string[]]@("$work\proj\dbo\StoredProcedures\T.sql"),
'Microsoft.Data.Tools.Schema.Sql.Sql150DatabaseSchemaProvider',
[Microsoft.SqlServer.Dac.DacExtractTarget]::SchemaObjectType))
$res = $cmp.Compare()
"differences listed : $($res.Differences.Count)"

$before = Get-Content "$work\proj\dbo\StoredProcedures\T.sql" -Raw
$pub = $res.PublishChangesToProject("$work\proj", [Microsoft.SqlServer.Dac.DacExtractTarget]::SchemaObjectType)
$after = Get-Content "$work\proj\dbo\StoredProcedures\T.sql" -Raw
"publish Success : $($pub.Success)"
"changed/added/deleted : $($pub.ChangedFiles.Count)/$($pub.AddedFiles.Count)/$($pub.DeletedFiles.Count)"
"file modified on disk : $($before -cne $after)"
```

**Expected behavior**
`PublishChangesToProject` updates comment-only differences it reported

**Impact**
Teams using the common SSMS template header (`-- Author / Create date / Description` above `CREATE`) get permanent phantom diffs in schema compare that no amount of clicking Apply resolves.

Contributor guide

Open the contributing guide

Research direction

Start with SchemaComparison.Compare() and SchemaComparisonResult.PublishChangesToProject(), then trace how SysCommentsObjectAnnotation exposes HeaderContents and CreateOffset. Run the PowerShell reproduction against the stated DacFx version and inspect the generated project file. Done means comment-only differences produce an update and header comments are preserved when real module changes are published.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp, sql
Domain
databases, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.