fix(transport): flush created-site ids before the connection pass — create-missing import failed FK 547 on real SQL Server

Caught live 2026-08-01 importing a bundle into the empty env2 cluster: a
create-missing Site has Id == 0 until SaveChanges on a relational provider,
and ApplyDataConnectionsAsync stamps DataConnection.SiteId as a raw scalar
(no navigation, no EF fix-up), so the insert violated
FK_DataConnections_Sites_SiteId. Every importer integration test runs on
the EF in-memory provider, which assigns ids eagerly on AddAsync — the
exact masking the in-code comment predicted. Fix: one SaveChangesAsync
between the site pass and the connection pass, riding the same outer
transaction (all-or-nothing preserved; the failed live import rolled back
cleanly). Regression test runs the create-missing path on SQLite
(CreateMissingSiteRelationalTests) — red without the fix, green with it.
This commit is contained in:
Joseph Doherty
2026-08-01 12:32:45 -04:00
parent 1c99d6fa8d
commit 0c9dffed78
2 changed files with 168 additions and 0 deletions
@@ -1515,6 +1515,14 @@ public sealed class BundleImporter : IBundleImporter
// ids by name.)
var siteBySourceIdentifier = await ApplySitesAsync(
content, nameMap, resolutionMap, user, summary, ct).ConfigureAwait(false);
// Flush BETWEEN the site pass and the connection pass: a create-missing
// site has Id == 0 until SaveChanges on a relational provider, and the
// connection pass stamps DataConnection.SiteId as a raw scalar (no EF
// navigation, so no fix-up) — without this flush the insert fails the
// FK on real SQL Server (FK_DataConnections_Sites_SiteId, error 547).
// The in-memory provider assigns ids eagerly on AddAsync, which is why
// in-process tests never hit this. Rides the same outer transaction.
await _dbContext.SaveChangesAsync(ct).ConfigureAwait(false);
var connectionMaps = await ApplyDataConnectionsAsync(
content, nameMap, siteBySourceIdentifier, resolutionMap, user, summary, ct).ConfigureAwait(false);
// Flush so site + connection surrogate ids are assigned (relational