You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
EF tests: run queries and round trips against SQL Server #81
The EF satellite's tests run queries and round trips on PostgreSQL (Npgsql) and SQLite, and SQL Server only for its model, built without a server (Directory.Packages.props, the EF test packages' comment; KeyGenerationTests). No test runs a query against SQL Server.
The EF Core README promises that .Value works in LINQ as it does in memory. SQL Server is where that is most likely to differ:
Collation. The default collation is case-insensitive, so Where(c => c.Code == code) and Contains/StartsWith over a string value object can match rows that are not equal in memory, where string equality is ordinal. Ordering follows the collation too.
Precision.datetime2 and decimal(p,s) round on write, as numeric(p,s) does on PostgreSQL (KB-034).
Keys. Key generation is checked on the model only; an identity or sequence key over a value object is never inserted and read back.
Proposal
Add a SQL Server leg to the EF round-trip and query tests, on Testcontainers (Testcontainers.MsSql), over the existing KeyShapes and QueryShapes catalogues. Each difference it finds is either a fix or a pinned fact in design/knowledge/ with its test, cited from the EF README where it changes what a consumer sees.
Done when
The EF tests run the query and round-trip shapes on SQL Server in CI (Linux runner; the container needs no Windows).
Every difference from in-memory behaviour is fixed or recorded as a KB entry, and the README states the ones a consumer must know.
What the SQL Server leg found (PR #142), measured on Azure SQL Edge locally and on SQL Server 2022 in CI:
No difference needed a change in src/. On SQL Server a value object answers as its wrapped type does, over the whole query catalogue (~10k cases) and the key catalogue (every shape × key kind, inserted and read back). The differences from memory are SQL Server's own, each pinned as a fact with a plain-EF test:
KB-048: text compares and orders ignoring case and trailing spaces (==, IN, LIKE, ORDER BY).
KB-049: a uniqueidentifier orders by its last group first.
KB-050: a decimal without a precision is decimal(18,2), read back at scale 2 (10.00) and rounded on write.
KB-051: time holds less than a day. A longer TimeSpan is refused in a column, and silently read as another value from a JSON column (1.02:00:00 → 01:02:00).
KB-052: SQL Server refuses MAX/MIN of a bit.
KB-053: EF translates EF.Functions.Greatest/Least only from compatibility level 160. At 160, the value object's SQL is the wrapped type's.
KB-054: datetime2 keeps every tick and reads a DateTime back with Kind Unspecified.
The other differences from memory are relational, shared with SQLite: a null .Value that throws in memory and is a NULL in SQL, and queries EF translates for neither. The EF README's new "On SQL Server" section states the ones a consumer meets.
Two side notes:
The catalogue's text values now mix case. That showed the SQLite test's in-memory Greatest/Least comparing strings by culture; it's ordinal now.
SQL Server 2022 doesn't start on an arm64 Mac under QEMU. TYPEKIT_MSSQL_IMAGE=mcr.microsoft.com/azure-sql-edge:latest runs it natively there (CONTRIBUTING).
Done in #142, merged into release/2.3.0 (4ff49f5): the query and key catalogues run on SQL Server 2022 in CI's Linux leg; seven differences pinned as KB-048 to KB-054, the EF README's "On SQL Server" section states them; nothing in src/ needed a change.
Activity
CaffeinatedCoder commentedon Oct 29, 2026
What the SQL Server leg found (PR #142), measured on Azure SQL Edge locally and on SQL Server 2022 in CI:
No difference needed a change in
src/. On SQL Server a value object answers as its wrapped type does, over the whole query catalogue (~10k cases) and the key catalogue (every shape × key kind, inserted and read back). The differences from memory are SQL Server's own, each pinned as a fact with a plain-EF test:==,IN,LIKE,ORDER BY).uniqueidentifierorders by its last group first.decimalwithout a precision isdecimal(18,2), read back at scale 2 (10.00) and rounded on write.timeholds less than a day. A longerTimeSpanis refused in a column, and silently read as another value from a JSON column (1.02:00:00→01:02:00).MAX/MINof abit.EF.Functions.Greatest/Leastonly from compatibility level 160. At 160, the value object's SQL is the wrapped type's.datetime2keeps every tick and reads aDateTimeback withKindUnspecified.The other differences from memory are relational, shared with SQLite: a null
.Valuethat throws in memory and is a NULL in SQL, and queries EF translates for neither. The EF README's new "On SQL Server" section states the ones a consumer meets.Two side notes:
Greatest/Leastcomparing strings by culture; it's ordinal now.TYPEKIT_MSSQL_IMAGE=mcr.microsoft.com/azure-sql-edge:latestruns it natively there (CONTRIBUTING).CaffeinatedCoder commentedon Oct 29, 2026
Done in #142, merged into
release/2.3.0(4ff49f5): the query and key catalogues run on SQL Server 2022 in CI's Linux leg; seven differences pinned as KB-048 to KB-054, the EF README's "On SQL Server" section states them; nothing insrc/needed a change.