From c4a9a12b37e460e12cc9f5e790c230f6fa0295e6 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Sat, 14 Jun 2025 17:58:26 +0200 Subject: [PATCH] Make NpgsqlArrayConverter not throw for struct arrays (#3552) Fixes #3551 (cherry picked from commit 19b9ff19f7a7c9d79704fb35a693eb3ac02b1cb1) --- .../ValueConversion/NpgsqlArrayConverter.cs | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/EFCore.PG/Storage/ValueConversion/NpgsqlArrayConverter.cs b/src/EFCore.PG/Storage/ValueConversion/NpgsqlArrayConverter.cs index 982d58eaa..b4eda1bad 100644 --- a/src/EFCore.PG/Storage/ValueConversion/NpgsqlArrayConverter.cs +++ b/src/EFCore.PG/Storage/ValueConversion/NpgsqlArrayConverter.cs @@ -185,11 +185,13 @@ private static Expression> ArrayConversionExpression NewArrayBounds(outputElementType, lengthVariable), + var t when typeof(TConcreteOutput).GetConstructor([typeof(int)]) is ConstructorInfo ctorWithLength => New(ctorWithLength, lengthVariable), + _ => New(typeof(TConcreteOutput)) + }) ]); if (indexer is not null) @@ -285,13 +287,21 @@ elementConversionExpression is null // return output; expressions.Add(output); - return Lambda>( - // First, check if the given array value is null and return null immediately if so - Condition( - ReferenceEqual(input, Constant(null)), - Constant(null, typeof(TOutput)), - Block(typeof(TOutput), variables, expressions)), - input); + Expression body = Block(typeof(TOutput), variables, expressions); + + // If the input type is a reference type, first check if the input array is null and return null + // (or default for output value type) if so, bypassing all of the logic above. + if (!typeof(TInput).IsValueType) + { + body = Condition( + ReferenceEqual(input, Constant(null, typeof(TInput))), + typeof(TOutput).IsValueType + ? New(typeof(TConcreteOutput)) + : Constant(null, typeof(TOutput)), + body); + } + + return Lambda>(body, input); } private static Expression ForLoop(