fix(data): five defects in model convert that silently lose or corrupt output - #190
Draft
david-hudec-networg wants to merge 5 commits into
Draft
Conversation
This was referenced Sep 1, 2026
david-hudec-networg
force-pushed
the
fix/data-model-convert-loses-model-content
branch
from
September 1, 2026 12:36
716dc16 to
7ac0ac2
Compare
A table with several lookups to one target rendered a single edge, while all its lookup columns still appeared - understating the model without looking broken. The duplicate guard keyed on (LeftSideTable, RighSideTable), ignoring which column the relationship ran through. The key now includes LeftSideRow. Genuine duplicates still collapse, which is what the guard is for. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Required, form-visible columns disappeared from the output with no warning, and a module whose only contribution was such an attribute read as contributing nothing. Rows of an optionset kind were deleted outright when their OptionSetName did not resolve. Three causes seen in real solutions: the global option set declares <options />, it is declared in a different module, or it is platform-owned. The row is kept and only OptionSetName is cleared. That is what ToDbDiagramNotation prefers over RowType, so leaving it set would reference an Enum that was never emitted; RowType is left alone so sql and edmx keep their own handling for the kind. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The same unchanged solution converted to a different file on every run, at identical length - so a generated diagram could not be committed, diffed, or compared across a model change. Two causes. Module seeded Colorhex from new Random(). And three file enumerations used Directory.GetFiles, which guarantees no ordering, so table, relationship and enum order followed the filesystem. Colour now derives from the module name with FNV-1a - not string.GetHashCode, which is randomised per process on .NET Core - and all three enumerations are ordered ordinally. Everyone's colours change; nothing could have depended on the old values. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Where an entity has a many-to-many with itself, the intersect table carried the same column twice, the same Ref twice, and the same EDMX navigation property twice. A DBML parser rejects the first two outright. Both sides resolved to <entity>id, and both legs carried the relationship name. The second column and the second leg's name are suffixed positionally. The real per-side names live in metadata (Entity1/Entity2IntersectAttribute) and are author-chosen - the platform's own example pairs connectionroleid with associatedconnectionroleid - so they cannot be derived from solution XML and are not guessed at here. Known limit: on the entity side EDMX still names the navigation property after the primary key row, so one duplicate remains there. The intersect side is clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…rejected Every plainsql conversion failed, and the error listed the formats it did support - contradicting the option's own help. The format is declared in the option's AllowedValues and fully implemented in the conversion switch, but was missing from the service's SupportedFormats guard three lines earlier. Added. A test now asserts every value the option advertises actually converts, so the two lists cannot drift apart again. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
david-hudec-networg
force-pushed
the
fix/data-model-convert-loses-model-content
branch
from
September 1, 2026 13:19
7ac0ac2 to
c040d75
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Five defects in
DataModelConverter, all silent: the output stays well-formed while losing or corrupting content, so nothing surfaces until you diff against the source declarations. Found across a product base and three customer solutions.(table, table), ignoring the column — one table with four lookups toaccountemitted one edge, with all four columns still listedLeftSideRowin the key<options />, declared in another module, or platform-ownedOptionSetName, leaveRowTypesosql/edmxkeep their own handlingDirectory.GetFilesat three sitesRef:twice, and the EDMX navigation property twice--target plainsqladvertised inAllowedValues, absent fromSupportedFormats, rejected on every callMeasured
ModellayerService/Project/ModelEnvironment/Bootstrap/ModelThree solutions × five targets: exit 0, idempotent by hash.
plainsqlnow emits DDL (351/528/684 lines).Tests
Seven unit tests over in-memory
XElementfixtures, no new dependencies. Verified as genuine regressions by reverting the converter tomasterand re-running: exactly the defect tests fail.Known limits, deliberately not fixed here
NavigationProperty(measured:talxis_producthas 9, one repeated). It is named after the PK row, not the relationship. The real per-side names live in metadata and are author-chosen — Microsoft's own example pairsconnectionroleidwithassociatedconnectionroleid— so they are not derivable from solution XML. The intersect side is clean.ribbonemits an empty document on all three solutions. Faithful: everyRibbonDiffXmlin them is self-closed.<entity>idis wrong for activity entities, and is not fixable here — the only layer that triggers key synthesis is also the layer that omitsIsActivity.🤖 Generated with Claude Code