diff --git a/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlArrayTypeMapping.cs b/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlArrayTypeMapping.cs index 749e3d3a0..15517dc7a 100644 --- a/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlArrayTypeMapping.cs +++ b/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlArrayTypeMapping.cs @@ -115,6 +115,18 @@ private static RelationalTypeMappingParameters CreateParameters(string storeType { providerElementType = providerElementType.MakeNullable(); } + else if (elementConverter.ConvertFromProviderExpression.ReturnType.IsNullableValueType() + && elementConverter.ConvertFromProviderExpression.ReturnType.UnwrapNullableType().IsAssignableFrom(elementType)) + { + var converterType = typeof(CastingConverter<,>).MakeGenericType( + elementType, + elementType.MakeNullable()); + + var converterTypeInstance = (ValueConverter)Activator.CreateInstance( + converterType)!; + + elementConverter = converterTypeInstance.ComposeWith(elementConverter); + } converter = (ValueConverter)Activator.CreateInstance( typeof(NpgsqlArrayConverter<,,>).MakeGenericType( diff --git a/test/EFCore.PG.FunctionalTests/Query/PrimitiveCollectionsQueryNpgsqlTest.cs b/test/EFCore.PG.FunctionalTests/Query/PrimitiveCollectionsQueryNpgsqlTest.cs index bf7b1ce34..1fb5743b1 100644 --- a/test/EFCore.PG.FunctionalTests/Query/PrimitiveCollectionsQueryNpgsqlTest.cs +++ b/test/EFCore.PG.FunctionalTests/Query/PrimitiveCollectionsQueryNpgsqlTest.cs @@ -2546,9 +2546,29 @@ WHERE NOT (p."NullableWrappedId" = ANY (@values) AND p."NullableWrappedId" = ANY """); } - public override Task Parameter_collection_of_structs_Contains_nullable_struct_with_nullable_comparer() - => Assert.ThrowsAnyAsync( - () => base.Parameter_collection_of_structs_Contains_nullable_struct_with_nullable_comparer()); + public override async Task Parameter_collection_of_structs_Contains_nullable_struct_with_nullable_comparer() + { + await base.Parameter_collection_of_structs_Contains_nullable_struct_with_nullable_comparer(); + + AssertSql( + """ +@values={ '22' +'33' } (DbType = Object) + +SELECT p."Id", p."Bool", p."Bools", p."DateTime", p."DateTimes", p."Enum", p."Enums", p."Int", p."Ints", p."NullableInt", p."NullableInts", p."NullableString", p."NullableStrings", p."NullableWrappedId", p."NullableWrappedIdWithNullableComparer", p."String", p."Strings", p."WrappedId" +FROM "PrimitiveCollectionsEntity" AS p +WHERE p."NullableWrappedIdWithNullableComparer" = ANY (@values) OR (p."NullableWrappedIdWithNullableComparer" IS NULL AND array_position(@values, NULL) IS NOT NULL) +""", + // + """ +@values={ '11' +'44' } (DbType = Object) + +SELECT p."Id", p."Bool", p."Bools", p."DateTime", p."DateTimes", p."Enum", p."Enums", p."Int", p."Ints", p."NullableInt", p."NullableInts", p."NullableString", p."NullableStrings", p."NullableWrappedId", p."NullableWrappedIdWithNullableComparer", p."String", p."Strings", p."WrappedId" +FROM "PrimitiveCollectionsEntity" AS p +WHERE NOT (p."NullableWrappedId" = ANY (@values) AND p."NullableWrappedId" = ANY (@values) IS NOT NULL) AND (p."NullableWrappedId" IS NOT NULL OR array_position(@values, NULL) IS NULL) +"""); + } public override async Task Parameter_collection_of_nullable_structs_Contains_struct() {