From 03180672b903a72c9f32c6970820b1570acdb993 Mon Sep 17 00:00:00 2001 From: Christiaan de Ridder Date: Sat, 7 Jun 2025 13:28:55 +0200 Subject: [PATCH 1/3] Add null URI to existing converter test --- .../DbContext/TestEntityWithConverters.cs | 3 +++ .../Tests/Basic/BasicTestsBase.cs | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/DbContext/TestEntityWithConverters.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/DbContext/TestEntityWithConverters.cs index 041a6be..7c58b6a 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/DbContext/TestEntityWithConverters.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/DbContext/TestEntityWithConverters.cs @@ -14,5 +14,8 @@ public class TestEntityWithConverters : TestEntityBase [Column("created_at")] public DateTime CreatedAt { get; set; } + + [Column("uri")] + public Uri? Uri { get; set; } } diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/Tests/Basic/BasicTestsBase.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/Tests/Basic/BasicTestsBase.cs index e69354f..2e2cb41 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/Tests/Basic/BasicTestsBase.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/Tests/Basic/BasicTestsBase.cs @@ -176,8 +176,8 @@ public async Task InsertEntities_AndReturn_WithEntityWithValueConverters(InsertS var entities = new List { - new TestEntityWithConverters() { Name = $"{_run}_Entity1", CreatedAt = now }, - new TestEntityWithConverters() { Name = $"{_run}_Entity2", CreatedAt = now.AddDays(-1) } + new TestEntityWithConverters() { Name = $"{_run}_Entity1", CreatedAt = now, Uri = null }, + new TestEntityWithConverters() { Name = $"{_run}_Entity2", CreatedAt = now.AddDays(-1), Uri = new Uri("http://example.com/test") } }; // Act From cca7af7543edd546dafa576659116d498db66047 Mon Sep 17 00:00:00 2001 From: Christiaan de Ridder Date: Sat, 7 Jun 2025 13:41:54 +0200 Subject: [PATCH 2/3] Don't invoke the type converter when the incoming complex type value is null --- .../Metadata/PropertyAccessor.cs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/PhenX.EntityFrameworkCore.BulkInsert/Metadata/PropertyAccessor.cs b/src/PhenX.EntityFrameworkCore.BulkInsert/Metadata/PropertyAccessor.cs index 8012739..3678269 100644 --- a/src/PhenX.EntityFrameworkCore.BulkInsert/Metadata/PropertyAccessor.cs +++ b/src/PhenX.EntityFrameworkCore.BulkInsert/Metadata/PropertyAccessor.cs @@ -27,9 +27,11 @@ internal static class PropertyAccessor { // Validate the converter input type matches property type var converterParamType = converter.Parameters[0].Type; - if (!converterParamType.IsAssignableFrom(propertyType) && !propertyType.IsAssignableFrom(converterParamType)) + if (!converterParamType.IsAssignableFrom(propertyType) && + !propertyType.IsAssignableFrom(converterParamType)) { - throw new ArgumentException($"Converter input must be assignable from property type ({propertyType} -> {converterParamType})"); + throw new ArgumentException( + $"Converter input must be assignable from property type ({propertyType} -> {converterParamType})"); } // If property type != converter param, convert @@ -39,7 +41,18 @@ internal static class PropertyAccessor converterInput = Expression.Convert(getterExpression, converterParamType); } - getterExpression = Expression.Invoke(converter, converterInput); + var invokeConverter = Expression.Invoke(converter, converterInput); + + if (propertyType.IsClass) + { + var nullCondition = Expression.Equal(getterExpression, Expression.Constant(null, propertyType)); + var nullResult = Expression.Constant(null, converter.ReturnType); + getterExpression = Expression.Condition(nullCondition, nullResult, invokeConverter); + } + else + { + getterExpression = invokeConverter; + } propertyType = getterExpression.Type; } From df333aaef1d9b3dd589ba034c36adc462ec339c3 Mon Sep 17 00:00:00 2001 From: Christiaan de Ridder Date: Sat, 7 Jun 2025 13:43:17 +0200 Subject: [PATCH 3/3] Undo formatting change --- .../Metadata/PropertyAccessor.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/PhenX.EntityFrameworkCore.BulkInsert/Metadata/PropertyAccessor.cs b/src/PhenX.EntityFrameworkCore.BulkInsert/Metadata/PropertyAccessor.cs index 3678269..582ce92 100644 --- a/src/PhenX.EntityFrameworkCore.BulkInsert/Metadata/PropertyAccessor.cs +++ b/src/PhenX.EntityFrameworkCore.BulkInsert/Metadata/PropertyAccessor.cs @@ -27,11 +27,9 @@ internal static class PropertyAccessor { // Validate the converter input type matches property type var converterParamType = converter.Parameters[0].Type; - if (!converterParamType.IsAssignableFrom(propertyType) && - !propertyType.IsAssignableFrom(converterParamType)) + if (!converterParamType.IsAssignableFrom(propertyType) && !propertyType.IsAssignableFrom(converterParamType)) { - throw new ArgumentException( - $"Converter input must be assignable from property type ({propertyType} -> {converterParamType})"); + throw new ArgumentException($"Converter input must be assignable from property type ({propertyType} -> {converterParamType})"); } // If property type != converter param, convert