From 337fc78893c48dd6ad3c9c3a2b69371d2ade9627 Mon Sep 17 00:00:00 2001 From: "Dailey, Alaric" Date: Sat, 24 Oct 2026 07:57:01 -0500 Subject: [PATCH] Map nullable struct query results --- Dapper/SqlMapper.cs | 5 ++++ Directory.Packages.props | 1 + tests/Dapper.Tests/Dapper.Tests.csproj | 1 + tests/Dapper.Tests/FakeDbTests.Issue1900.cs | 33 +++++++++++++++++++++ 4 files changed, 40 insertions(+) create mode 100644 tests/Dapper.Tests/FakeDbTests.Issue1900.cs diff --git a/Dapper/SqlMapper.cs b/Dapper/SqlMapper.cs index 8f3956cab..2d19101ff 100644 --- a/Dapper/SqlMapper.cs +++ b/Dapper/SqlMapper.cs @@ -1964,6 +1964,11 @@ private static Func GetDeserializer(Type type, DbDataReade { return GetDapperRowDeserializer(reader, startBound, length, returnNullIfFirstMissing); } + + if (type.IsValueType && Nullable.GetUnderlyingType(type) is Type nullableType && !nullableType.IsEnum) + { + return GetDeserializer(nullableType, reader, startBound, length, returnNullIfFirstMissing); + } Type? underlyingType = null; bool useGetFieldValue = false; diff --git a/Directory.Packages.props b/Directory.Packages.props index 2f91a3cca..b1e42ba41 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -38,6 +38,7 @@ + diff --git a/tests/Dapper.Tests/Dapper.Tests.csproj b/tests/Dapper.Tests/Dapper.Tests.csproj index 93b498618..e9eab6b88 100644 --- a/tests/Dapper.Tests/Dapper.Tests.csproj +++ b/tests/Dapper.Tests/Dapper.Tests.csproj @@ -32,6 +32,7 @@ + diff --git a/tests/Dapper.Tests/FakeDbTests.Issue1900.cs b/tests/Dapper.Tests/FakeDbTests.Issue1900.cs new file mode 100644 index 000000000..df2d3f708 --- /dev/null +++ b/tests/Dapper.Tests/FakeDbTests.Issue1900.cs @@ -0,0 +1,33 @@ +#if !NET481 +using System.Collections.Generic; +using pengdows.crud.fakeDb; +using Xunit; + +namespace Dapper.Tests; + +public sealed class FakeDbIssue1900Tests +{ + [Fact] + public void QuerySingleNullableStructMapsTheRow() + { + using var connection = new fakeDbConnection(new FakeDataStore()); + connection.EnqueueReaderResult(new[] + { + new Dictionary { ["ID"] = 1, ["Name"] = "Something" }, + }); + connection.Open(); + + var result = connection.QuerySingle("select ID, Name"); + + Assert.True(result.HasValue); + Assert.Equal(1, result.Value.ID); + Assert.Equal("Something", result.Value.Name); + } + + private struct Foo + { + public int ID { get; set; } + public string? Name { get; set; } + } +} +#endif