Repository navigation
Scaffold foreign keys whose column type differs from the principal key - #39633
Open
ajcvickers wants to merge 1 commit into
Open
ajcvickers wants to merge 1 commit into
ajcvickers wants to merge 1 commit into
Conversation
Fixes dotnet#19793 Reverse engineering threw InvalidOperationException when a foreign key column and the principal key column it references scaffolded to different CLR types, for example a bigint column referencing an int key, or NUMBER(12,0) referencing NUMBER. This aborted scaffolding of the whole database, because EF can't map an entity type whose foreign key and principal key properties have different CLR types. Now, where it is safe, the dependent column is scaffolded with the CLR type of the principal column and keeps its own store type through HasColumnType, so EF uses a value converter. It is safe when: - the column references principals of a single CLR type, and is not itself referenced by another foreign key; - the principal columns are a key or unique index of the principal; - the principal CLR type can't overflow the column (integral types only change to a type with a smaller or equal range, decimal and integral types can be mixed, and any other mix of types is left alone); - the column is not a row version and has no default value; and - the type mapping source can map the principal CLR type to the store type. All the columns of a foreign key are changed together or not at all. In every other case the foreign key is skipped with a new warning instead of failing scaffolding. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
ajcvickers
force-pushed
the
fix-19793-scaffold-fk-type-mismatch
branch
from
November 14, 2026 11:53
22cca54 to
8fff764
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.
Fixes #19793
Reverse engineering threw
InvalidOperationExceptionwhen a foreign key column and the principal key column it references scaffolded to different CLR types, for example abigintcolumn referencing anintkey, orNUMBER(12,0)referencingNUMBERon Oracle. This aborted scaffolding of the whole database, because EF can't map an entity type whose foreign key and principal key properties have different CLR types.Behavior
Where it is safe, the dependent column is now scaffolded with the CLR type of the principal column and keeps its own store type through
HasColumnType, so EF uses a value converter:It is safe when all of these hold:
decimaland integral types can be mixed, which covers the OracleNUMBERcase. Any other mix (string, Guid, binary, float, bool) is left alone.The columns of a foreign key are changed together or not at all. The check uses the column's own store type, not the CLR type hint that SQLite derives from the data in a column, so a SQLite
INTEGERcolumn hinted asintcan still reference anINTEGERkey.In every other case the foreign key is skipped with a new warning, and scaffolding continues, instead of failing:
This follows what was agreed in the issue: at least don't abort scaffolding, and add the converter in scaffolding when it is low cost.
Behavior change to note
Databases that previously failed to scaffold now succeed. Foreign key columns in them can have a different CLR type from the column's default for its store type, with an explicit
HasColumnType, and some foreign keys are skipped with the new warning. Databases that scaffolded before produce the same output.Not handled
DEFAULT 0) is not retyped, so its foreign key is skipped with the warning.Tests
RelationalScaffoldingModelFactoryTestcover wider and narrower dependent types,decimalagainst integral, non-numeric mismatches, default values, row versions, columns without a store type, self-referencing and composite foreign keys (including a cascade across foreign keys that share columns), primary key, unique index and unique constraint columns, principals that are not keys, repeatedCreatecalls, and the SQLiteClrTypehint on either end.CSharpDbContextGeneratorTestgenerates code from a scaffolded model with a mismatched foreign key, compiles it, and checks the compiled model.test.cmdpasses locally (28 test projects), with SQL Server tests run against a local container.🤖 Generated with Claude Code