Skip to content

Commit

Permalink
EF value converter shouldn't do round-trip conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
PawelGerr committed Oct 23, 2024
1 parent 6c26b5e commit 87635d8
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 3 deletions.
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<Copyright>(c) $([System.DateTime]::Now.Year), Pawel Gerr. All rights reserved.</Copyright>
<VersionPrefix>7.5.2</VersionPrefix>
<VersionPrefix>7.5.3</VersionPrefix>
<Authors>Pawel Gerr</Authors>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageProjectUrl>https://github.com/PawelGerr/Thinktecture.Runtime.Extensions</PackageProjectUrl>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,19 +100,44 @@ private sealed class ValueObjectValueConverter<T, TKey> : ValueConverter<T, TKey
where T : IValueObjectFactory<TKey>, IValueObjectConvertable<TKey>
where TKey : notnull
{
/// <inheritdoc />
public override Func<object?, object?> ConvertToProvider { get; }

public ValueObjectValueConverter(bool useConstructor)
: base(static o => o.ToValue(), GetConverterFromKey<T, TKey>(useConstructor))
{
ConvertToProvider = o => o switch
{
null => null,
TKey key => key, // useful for comparisons of value objects with its key types
_ => ((T)o).ToValue()
};
}
}

private sealed class ValidatableEnumValueConverter<TEnum, TKey> : ValueConverter<TEnum, TKey>
where TEnum : IValidatableEnum, IValueObjectFactory<TKey>, IValueObjectConvertable<TKey>
where TKey : notnull
{
/// <inheritdoc />
public override Func<object?, object?> ConvertToProvider { get; }

public ValidatableEnumValueConverter(bool validateOnWrite)
: base(GetKeyProvider(validateOnWrite), GetConverterFromKey<TEnum, TKey>(false))
{
ConvertToProvider = validateOnWrite
? o => o switch
{
null => null,
TKey key => key, // useful for comparisons of value objects with its key types
_ => GetKeyIfValid((TEnum)o)
}
: o => o switch
{
null => null,
TKey key => key, // useful for comparisons of value objects with its key types
_ => ((TEnum)o).ToValue()
};
}

private static Expression<Func<TEnum, TKey>> GetKeyProvider(bool validateOnWrite)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Thinktecture.Runtime.Tests.TestEntities;
Expand Down Expand Up @@ -79,6 +80,15 @@ UPDATE TestEntities_with_Enum_and_ValueObjects
loadedEntity.Boundary.Upper.Should().Be(20);
}

[Fact]
public async Task Should_not_roundtrip_convert_underlying_type_to_value_object_and_back_to_underlying_type()
{
await _ctx.TestEntities_with_Enum_and_ValueObjects
.Where(e => e.IntBasedStructValueObject == 42
&& e.TestSmartEnum_Struct_IntBased == 42)
.ToListAsync();
}

public void Dispose()
{
_ctx.Dispose();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
namespace Thinktecture.Runtime.Tests.TestEnums;

// ReSharper disable once InconsistentNaming
[SmartEnum<int>(IsValidatable = true)]
[SmartEnum<int>(IsValidatable = true,
ComparisonOperators = OperatorsGeneration.DefaultWithKeyTypeOverloads,
EqualityComparisonOperators = OperatorsGeneration.DefaultWithKeyTypeOverloads)]
public readonly partial struct TestSmartEnum_Struct_IntBased
{
public static readonly TestSmartEnum_Struct_IntBased Value1 = new(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ namespace Thinktecture.Runtime.Tests.TestValueObjects;

[ValueObject<int>(KeyMemberKind = ValueObjectMemberKind.Property,
KeyMemberName = "Property",
KeyMemberAccessModifier = ValueObjectAccessModifier.Public)]
KeyMemberAccessModifier = ValueObjectAccessModifier.Public,
EqualityComparisonOperators = OperatorsGeneration.DefaultWithKeyTypeOverloads,
ComparisonOperators = OperatorsGeneration.DefaultWithKeyTypeOverloads)]
public readonly partial struct IntBasedStructValueObject
{
}

0 comments on commit 87635d8

Please sign in to comment.