#2227·Dapper

Query<DateOnly> / Query<TimeOnly> (scalar form) silently return default(T)

Author: mgravellCreated Aug 20, 2026Updated Aug 20, 2026

Found while probing #2226, but this one is independent of provider and Npgsql version — and it is silent, which makes it the more serious of the two.

With Dapper 2.1.72, a single-column query materialized as a bare DateOnly/TimeOnly returns the default value with no error:

probe result
QuerySingle<DateOnly>("select '2021-01-01'::date") (Npgsql 9 and 10) 0001-01-01 ❌ silent
QuerySingle<DateOnly>("select cast('2021-01-01' as date)") (SqlClient) 0001-01-01 ❌ silent
QuerySingle<TimeOnly>("select '03:03:03'::time") (Npgsql) 00:00 ❌ silent
ExecuteScalar<DateOnly>("select '2021-01-01'::date") (Npgsql) 2021-01-01
POCO with a DateOnly member (Npgsql 10) 2021-01-01

ExecuteScalar<DateOnly> and the member path are fine, so this looks like the Query<T> simple-vs-complex type decision not recognising DateOnly/TimeOnly as scalar types (Type.GetTypeCode reports Object for both) — the member-mapping deserializer then finds nothing to bind on a struct with no settable members and hands back a default instance. The type map entries added in #2051 (DoNotSetFieldValue/UseGetFieldValue) apparently don't reach this decision.

Wrong data with no exception is the worst failure mode available, so flagging it separately from #2226 rather than folding it in.