Skip to content

Commit 19b9ff1

Browse files
authored
Make NpgsqlArrayConverter not throw for struct arrays (#3552)
Fixes #3551
1 parent 91fd2fe commit 19b9ff1

File tree

1 file changed

+22
-12
lines changed

1 file changed

+22
-12
lines changed

src/EFCore.PG/Storage/ValueConversion/NpgsqlArrayConverter.cs

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -185,11 +185,13 @@ private static Expression<Func<TInput, TOutput>> ArrayConversionExpression<TInpu
185185
// Allocate an output array or list
186186
// var result = new int[length];
187187
Assign(
188-
output, typeof(TConcreteOutput).IsArray
189-
? NewArrayBounds(outputElementType, lengthVariable)
190-
: typeof(TConcreteOutput).GetConstructor([typeof(int)]) is ConstructorInfo ctorWithLength
191-
? New(ctorWithLength, lengthVariable)
192-
: New(typeof(TConcreteOutput).GetConstructor([])!))
188+
output,
189+
typeof(TConcreteOutput) switch
190+
{
191+
var t when t.IsArray => NewArrayBounds(outputElementType, lengthVariable),
192+
var t when typeof(TConcreteOutput).GetConstructor([typeof(int)]) is ConstructorInfo ctorWithLength => New(ctorWithLength, lengthVariable),
193+
_ => New(typeof(TConcreteOutput))
194+
})
193195
]);
194196

195197
if (indexer is not null)
@@ -285,13 +287,21 @@ elementConversionExpression is null
285287
// return output;
286288
expressions.Add(output);
287289

288-
return Lambda<Func<TInput, TOutput>>(
289-
// First, check if the given array value is null and return null immediately if so
290-
Condition(
291-
ReferenceEqual(input, Constant(null)),
292-
Constant(null, typeof(TOutput)),
293-
Block(typeof(TOutput), variables, expressions)),
294-
input);
290+
Expression body = Block(typeof(TOutput), variables, expressions);
291+
292+
// If the input type is a reference type, first check if the input array is null and return null
293+
// (or default for output value type) if so, bypassing all of the logic above.
294+
if (!typeof(TInput).IsValueType)
295+
{
296+
body = Condition(
297+
ReferenceEqual(input, Constant(null, typeof(TInput))),
298+
typeof(TOutput).IsValueType
299+
? New(typeof(TConcreteOutput))
300+
: Constant(null, typeof(TOutput)),
301+
body);
302+
}
303+
304+
return Lambda<Func<TInput, TOutput>>(body, input);
295305
}
296306

297307
private static Expression ForLoop(

0 commit comments

Comments
 (0)