From b242d343c2e8549f4672ec43fccccf8b7f835bc6 Mon Sep 17 00:00:00 2001 From: Pawel Gerr Date: Thu, 24 Oct 2024 07:47:46 +0200 Subject: [PATCH 1/2] EF value converter tries to convert provided value to key type to improve user experience --- .../ValueObjectValueConverterFactory.cs | 14 +++++-- .../ValueObjectValueConverterFactoryTests.cs | 38 ++++++++++++++++++- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/Thinktecture.Runtime.Extensions.EntityFrameworkCore.Sources/EntityFrameworkCore/Storage/ValueConversion/ValueObjectValueConverterFactory.cs b/src/Thinktecture.Runtime.Extensions.EntityFrameworkCore.Sources/EntityFrameworkCore/Storage/ValueConversion/ValueObjectValueConverterFactory.cs index b0b7c2fa..722fb9e6 100644 --- a/src/Thinktecture.Runtime.Extensions.EntityFrameworkCore.Sources/EntityFrameworkCore/Storage/ValueConversion/ValueObjectValueConverterFactory.cs +++ b/src/Thinktecture.Runtime.Extensions.EntityFrameworkCore.Sources/EntityFrameworkCore/Storage/ValueConversion/ValueObjectValueConverterFactory.cs @@ -96,6 +96,11 @@ private static Expression> GetConverterFromKey(bool useCo return (Expression>)(factoryMethod ?? throw new InvalidOperationException($"A value converter cannot be created for the type '{typeof(T).Name}' because it has no factory methods.")); } + private static T Convert(object value) + { + return (T)System.Convert.ChangeType(value, typeof(T)); + } + private sealed class ValueObjectValueConverter : ValueConverter where T : IValueObjectFactory, IValueObjectConvertable where TKey : notnull @@ -110,7 +115,8 @@ public ValueObjectValueConverter(bool useConstructor) { null => null, TKey key => key, // useful for comparisons of value objects with its key types - _ => ((T)o).ToValue() + T obj => obj.ToValue(), + _ => Convert(o) }; } } @@ -130,13 +136,15 @@ public ValidatableEnumValueConverter(bool validateOnWrite) { null => null, TKey key => key, // useful for comparisons of value objects with its key types - _ => GetKeyIfValid((TEnum)o) + TEnum obj => GetKeyIfValid(obj), + _ => Convert(o) } : o => o switch { null => null, TKey key => key, // useful for comparisons of value objects with its key types - _ => ((TEnum)o).ToValue() + TEnum obj => obj.ToValue(), + _ => Convert(o) }; } diff --git a/test/Thinktecture.Runtime.Extensions.EntityFrameworkCore.Tests.Sources/EntityFrameworkCore/ValueConversion/ValueObjectValueConverterFactoryTests.cs b/test/Thinktecture.Runtime.Extensions.EntityFrameworkCore.Tests.Sources/EntityFrameworkCore/ValueConversion/ValueObjectValueConverterFactoryTests.cs index 153f1383..ac620e84 100644 --- a/test/Thinktecture.Runtime.Extensions.EntityFrameworkCore.Tests.Sources/EntityFrameworkCore/ValueConversion/ValueObjectValueConverterFactoryTests.cs +++ b/test/Thinktecture.Runtime.Extensions.EntityFrameworkCore.Tests.Sources/EntityFrameworkCore/ValueConversion/ValueObjectValueConverterFactoryTests.cs @@ -83,9 +83,43 @@ UPDATE TestEntities_with_Enum_and_ValueObjects [Fact] public async Task Should_not_roundtrip_convert_underlying_type_to_value_object_and_back_to_underlying_type() { + var item = TestSmartEnum_Struct_IntBased.Value1; + TestSmartEnum_Struct_IntBased? nullableItem = item; + + var valueObj = IntBasedStructValueObject.Create(42); + IntBasedStructValueObject? nullableValueObj = valueObj; + + long int64 = 42; + long? nullableInt64 = int64; + int int32 = 42; + int? nullableInt32 = int32; + short int16 = 42; + short? nullableInt16 = int16; + decimal deci = 42; + decimal? nullableDecimal = deci; + await _ctx.TestEntities_with_Enum_and_ValueObjects - .Where(e => e.IntBasedStructValueObject == 42 - && e.TestSmartEnum_Struct_IntBased == 42) + .Where(e => e.TestSmartEnum_Struct_IntBased == item + && e.TestSmartEnum_Struct_IntBased == nullableItem + && e.IntBasedStructValueObject == valueObj + && e.IntBasedStructValueObject == nullableValueObj + && e.IntBasedStructValueObject == int64 + && e.TestSmartEnum_Struct_IntBased == int64 + && e.IntBasedStructValueObject == nullableInt64 + && e.TestSmartEnum_Struct_IntBased == nullableInt64 + && e.IntBasedStructValueObject == int32 + && e.TestSmartEnum_Struct_IntBased == int32 + && e.IntBasedStructValueObject == nullableInt32 + && e.TestSmartEnum_Struct_IntBased == nullableInt32 + && e.IntBasedStructValueObject == int16 + && e.TestSmartEnum_Struct_IntBased == int16 + && e.IntBasedStructValueObject == nullableInt16 + && e.TestSmartEnum_Struct_IntBased == nullableInt16 + && e.IntBasedStructValueObject == deci + && e.TestSmartEnum_Struct_IntBased == deci + && e.IntBasedStructValueObject == nullableDecimal + && e.TestSmartEnum_Struct_IntBased == nullableDecimal + ) .ToListAsync(); } From 3ad1376f550dbf9da3c17a82e253419ef6ee1e61 Mon Sep 17 00:00:00 2001 From: Pawel Gerr Date: Thu, 24 Oct 2024 07:52:06 +0200 Subject: [PATCH 2/2] Updated message pack due to known vulnerability in older version --- Directory.Packages.props | 54 ++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 7356548f..7c985a27 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -1,28 +1,28 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file