Skip to content

Fix Oracle EF Core mapping test and run the Oracle suite in CI (#394) - #395

Merged
jeremydmiller merged 2 commits into
masterfrom
fix/efcore-oracle-pk-casing
Jul 29, 2026
Merged

Fix Oracle EF Core mapping test and run the Oracle suite in CI (#394)#395
jeremydmiller merged 2 commits into
masterfrom
fix/efcore-oracle-pk-casing

Conversation

@jeremydmiller

@jeremydmiller jeremydmiller commented Jul 29, 2026

Copy link
Copy Markdown
Member

Fixes #394. Two parts: the failing assertion, and the CI gap that let it stay failing.

1. The test asserted a casing the mapping never produced

Oracle.end_to_end.can_map_entity_to_table failed against a live Oracle instance:

Shouldly.ShouldAssertException : table.PrimaryKeyColumns
    should contain "id"
    but was actually ["Id"]

There is no product bug. MapToTable sets PreserveIdentifierCase = true deliberately, so column names carry EF Core's casing verbatim. Dumping the mapped table confirms it:

Id, BoolValue, CASCADE_VAL, DateOnlyValue, DT_OFFSET_VAL, DateTimeValue,
GuidValue, IntValue, NULL_*, StringValue, TimeOnlyValue

Columns take the name given to HasColumnName() where the model configures one, and the CLR property name otherwise. Nothing is lowercased. MyEntity.Id has no HasColumnName(), so PrimaryKeyColumns returning ["Id"] is correct.

My initial reading in #394 — that PrimaryKeyColumns was failing to lowercase along with the other columns — was mistaken, and I have corrected the issue.

Why it went unnoticed, and why this is not a one-character fix. Weasel.Oracle's Table compares names with OrdinalIgnoreCase, and HasColumn uses that comparison, so

table.HasColumn("intvalue").ShouldBeTrue();

succeeds against a column actually named "IntValue" — and would succeed for any casing whatsoever. The test held fourteen assertions that could not fail plus one case-sensitive assertion written against a convention the code never had. Flipping "id" to "Id" would leave it just as unable to catch a casing regression, so the HasColumn series is replaced with a single assertion on the full column-name set, and the // Oracle lowercases column names in Weasel comment is corrected.

2. CI could not see any of this

ci-build-efcore.yml ran with --filter "FullyQualifiedName!~Oracle" because the workflow had no Oracle service, so the Oracle/ folder never executed. Fixing the assertion without fixing that would leave the next Oracle EF regression equally invisible.

Oracle now comes up through docker compose rather than as a GitHub service container, matching ci-build-oracle.yml — the container needs docker/oracle mounted as init SQL to grant the weasel user its schema privileges, which a service container cannot do.

  • Scoped to the net9.0 leg only. The Oracle EF provider has no net10.0 support, so the csproj already compiles that folder out of the net10.0 build; starting a database it cannot use would only add several minutes.
  • The start step runs before the SDK install and the health wait after the build, so Oracle warms up during restore and build instead of blocking on its own.
  • Job timeout raised to 45 minutes to match ci-build-oracle.yml, with docker compose down on if: always().
  • The filter is dropped entirely rather than narrowed: with Oracle available on net9.0, and both the Oracle and MySql folders compiled out of net10.0, each framework runs everything it actually built.

Verification

Locally against Docker: EF Core Oracle tests 3 passed / 1 skipped — the skip is the pre-existing ORA-03048 one, untouched — and Weasel.Oracle.Tests 186 passed on both net9.0 and net10.0.

The CI wiring itself can only be verified in CI, since this is the first time these tests will run there. The EF Core net9.0 check on this PR is the real test of part 2.

🤖 Generated with Claude Code

jeremydmiller and others added 2 commits July 29, 2026 06:29
can_map_entity_to_table asserted PrimaryKeyColumns contains a lowercase "id".
The mapping has never produced that. MapToTable sets PreserveIdentifierCase, so
column names carry EF Core's casing verbatim - the names given to
HasColumnName() where the model configures one, the CLR property name otherwise.
Dumping the mapped table confirms it:

  Id, BoolValue, CASCADE_VAL, DateOnlyValue, DT_OFFSET_VAL, DateTimeValue,
  GuidValue, IntValue, NULL_*, StringValue, TimeOnlyValue

So the product was right and the assertion was wrong. My first reading in #394 -
that PrimaryKeyColumns was failing to lowercase along with the other columns -
was mistaken: nothing lowercases them.

The reason that went unnoticed is worth fixing too. Oracle's Table compares
names with OrdinalIgnoreCase, so the surrounding HasColumn("intvalue") calls
succeed against a column actually named "IntValue" and assert nothing about
casing at all. PrimaryKeyColumns.ShouldContain was the one case-sensitive
assertion in the test, which is why it alone failed.

Replaced the HasColumn series with one assertion on the full column-name set, so
the test pins the casing contract instead of passing regardless of it, and fixed
the comment claiming "Oracle lowercases column names in Weasel".

Predates the xUnit v3 migration: verified the identical failure on the
pre-migration commit. CI never caught it because ci-build-efcore.yml has no
Oracle service and filters the folder out.

Verified against local Docker: EF Core Oracle 3 passed / 1 pre-existing skip,
and Weasel.Oracle.Tests 186 on both target frameworks.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…el#394)

The EF Core workflow ran with --filter "FullyQualifiedName!~Oracle" because it
had no Oracle service, so the Oracle/ folder never executed in CI. That is how
can_map_entity_to_table sat red for anyone running the suite locally without
anything noticing - fixing the assertion is only half the issue.

Oracle comes up through docker compose rather than as a GitHub service
container, matching ci-build-oracle.yml: the container needs docker/oracle
mounted as init SQL to grant the weasel user its schema privileges, which a
service container cannot do.

Scoped to the net9.0 leg with an if condition. The Oracle EF provider has no
net10.0 support, so the csproj already compiles the Oracle folder out of that
build - starting a database it cannot use would just add several minutes.

The start step goes before the SDK install and the health wait after the build,
so Oracle warms up during restore and build rather than blocking on its own. The
job timeout goes to 45 minutes to match ci-build-oracle.yml, and a `docker
compose down` runs with if: always().

The test filter is dropped entirely rather than narrowed: with Oracle available
on net9.0, and both the Oracle and MySql folders compiled out of net10.0, each
framework should simply run everything it built.

This is the first time the Oracle EF tests will execute in CI, so CI is the only
place it can be verified; locally they pass 3 with 1 pre-existing skip.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@jeremydmiller jeremydmiller changed the title Fix Oracle EF Core mapping test to assert the real column casing (#394) Fix Oracle EF Core mapping test and run the Oracle suite in CI (#394) Jul 29, 2026
@jeremydmiller
jeremydmiller merged commit 860eb60 into master Jul 29, 2026
16 checks passed
@jeremydmiller
jeremydmiller deleted the fix/efcore-oracle-pk-casing branch July 29, 2026 11:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

EF Core Oracle test asserts a lowercase PK column name the mapping never produces

1 participant