Skip to content

Commit fcfb45b

Browse files
committed
Merge branch 'releases/8.x.x'
2 parents b4b4749 + 5f90613 commit fcfb45b

File tree

11 files changed

+121
-8
lines changed

11 files changed

+121
-8
lines changed

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<Copyright>(c) $([System.DateTime]::Now.Year), Pawel Gerr. All rights reserved.</Copyright>
5-
<VersionPrefix>9.0.1</VersionPrefix>
5+
<VersionPrefix>9.1.0</VersionPrefix>
66
<Authors>Pawel Gerr</Authors>
77
<GenerateDocumentationFile>true</GenerateDocumentationFile>
88
<PackageProjectUrl>https://github.com/PawelGerr/Thinktecture.Runtime.Extensions</PackageProjectUrl>

src/Thinktecture.Runtime.Extensions.EntityFrameworkCore.Sources/EntityFrameworkCore/Conventions/ThinktectureConventionSetPlugin.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ public ConventionSet ModifyConventions(ConventionSet conventionSet)
2222
conventionSet.NavigationAddedConventions.Add(convention);
2323
conventionSet.PropertyAddedConventions.Add(convention);
2424
conventionSet.EntityTypeAddedConventions.Add(convention);
25+
26+
#if PRIMITIVE_COLLECTIONS
27+
conventionSet.PropertyElementTypeChangedConventions.Add(convention);
28+
#endif
2529
}
2630

2731
return conventionSet;

src/Thinktecture.Runtime.Extensions.EntityFrameworkCore.Sources/EntityFrameworkCore/Conventions/ThinktectureConventionsPlugin.cs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,13 @@
88

99
namespace Thinktecture.EntityFrameworkCore.Conventions;
1010

11-
internal sealed class ThinktectureConventionsPlugin : INavigationAddedConvention, IPropertyAddedConvention, IEntityTypeAddedConvention
11+
internal sealed class ThinktectureConventionsPlugin
12+
: INavigationAddedConvention,
13+
IPropertyAddedConvention,
14+
IEntityTypeAddedConvention
15+
#if PRIMITIVE_COLLECTIONS
16+
, IPropertyElementTypeChangedConvention
17+
#endif
1218
{
1319
private readonly bool _useConstructorForRead;
1420
private readonly Action<IConventionProperty> _configureEnumsAndKeyedValueObjects;
@@ -99,6 +105,31 @@ public void ProcessPropertyAdded(IConventionPropertyBuilder propertyBuilder, ICo
99105
ProcessProperty(propertyBuilder.Metadata);
100106
}
101107

108+
#if PRIMITIVE_COLLECTIONS
109+
public void ProcessPropertyElementTypeChanged(
110+
IConventionPropertyBuilder propertyBuilder,
111+
IElementType? newElementType,
112+
IElementType? oldElementType,
113+
IConventionContext<IElementType> context)
114+
{
115+
var elementType = propertyBuilder.Metadata.GetElementType();
116+
117+
if (elementType is null)
118+
return;
119+
120+
var valueConverter = elementType.GetValueConverter();
121+
122+
if (valueConverter is not null)
123+
return;
124+
125+
if (MetadataLookup.Find(elementType.ClrType) is not Metadata.Keyed metadata)
126+
return;
127+
128+
elementType.SetValueConverter(GetValueConverter(metadata));
129+
_configureEnumsAndKeyedValueObjects(propertyBuilder.Metadata);
130+
}
131+
#endif
132+
102133
private void ProcessNavigation(IConventionNavigation navigation)
103134
{
104135
var naviType = navigation.ClrType;

src/Thinktecture.Runtime.Extensions.EntityFrameworkCore.Sources/Extensions/EntityTypeBuilderExtensions.cs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ private static void AddConverterToNonNavigation(
337337
if (entity.IsIgnored(propertyInfo.Name))
338338
return;
339339

340-
// wil be handled by AddConverterForScalarProperties
340+
// will be handled by AddConverterForScalarProperties
341341
if (entity.FindProperty(propertyInfo) is not null)
342342
return;
343343

@@ -459,13 +459,41 @@ private static void AddConverterForScalarProperties(
459459
if (valueConverter is not null)
460460
continue;
461461

462+
#if PRIMITIVE_COLLECTIONS
463+
if (property.IsPrimitiveCollection)
464+
{
465+
AddConverterForPrimitiveCollections(property, useConstructorForRead, configure);
466+
return;
467+
}
468+
#endif
469+
462470
if (MetadataLookup.Find(property.ClrType) is not Metadata.Keyed metadata)
463471
continue;
464472

465473
SetConverterAndExecuteCallback(useConstructorForRead, configure, property, metadata);
466474
}
467475
}
468476

477+
#if PRIMITIVE_COLLECTIONS
478+
private static void AddConverterForPrimitiveCollections(
479+
IMutableProperty property,
480+
bool useConstructorForRead,
481+
Action<IMutableProperty> configure)
482+
{
483+
var elementType = property.GetElementType();
484+
485+
if (elementType is null)
486+
return;
487+
488+
if (MetadataLookup.Find(elementType.ClrType) is not Metadata.Keyed metadata)
489+
return;
490+
491+
var valueConverter = ThinktectureValueConverterFactory.Create(metadata, useConstructorForRead);
492+
elementType.SetValueConverter(valueConverter);
493+
configure(property);
494+
}
495+
#endif
496+
469497
#if COMPLEX_TYPES
470498
private static void AddConverterForComplexProperties(
471499
IMutableTypeBase entity,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#if PRIMITIVE_COLLECTIONS
2+
using Microsoft.EntityFrameworkCore.Metadata.Builders;
3+
using Thinktecture.EntityFrameworkCore.Storage.ValueConversion;
4+
5+
namespace Thinktecture;
6+
7+
/// <summary>
8+
/// Provides extension methods for the <see cref="PrimitiveCollectionBuilder{TProperty}"/> class to configure value object conversions.
9+
/// </summary>
10+
public static class PrimitiveCollectionBuilderExtensions
11+
{
12+
/// <summary>
13+
/// Configures a primitive collection to use value object conversion.
14+
/// </summary>
15+
/// <typeparam name="TProperty">The element type of the collection.</typeparam>
16+
/// <param name="primitiveCollectionBuilder">The primitive collection builder.</param>
17+
/// <param name="useConstructorForRead">For keyed value objects only. Whether to use the constructor when reading from the database.</param>
18+
/// <returns>The primitive collection builder for chaining.</returns>
19+
public static PrimitiveCollectionBuilder<TProperty> HasThinktectureValueConverter<TProperty>(
20+
this PrimitiveCollectionBuilder<TProperty> primitiveCollectionBuilder,
21+
bool useConstructorForRead = true)
22+
{
23+
var elementType = primitiveCollectionBuilder.ElementType();
24+
var converter = ThinktectureValueConverterFactory.Create(elementType.Metadata.ClrType, useConstructorForRead);
25+
elementType.HasConversion(converter);
26+
27+
return primitiveCollectionBuilder;
28+
}
29+
}
30+
#endif

src/Thinktecture.Runtime.Extensions.EntityFrameworkCore8/Thinktecture.Runtime.Extensions.EntityFrameworkCore8.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<PropertyGroup>
44
<Description>Extends Entity Framework Core to support some components from Thinktecture.Runtime.Extensions.</Description>
55
<PackageTags>smart-enum;value-object;discriminated-union;EntityFrameworkCore</PackageTags>
6-
<DefineConstants>$(DefineConstants);COMPLEX_TYPES;USE_FIND_COMPLEX_PROPERTY_FIX;</DefineConstants>
6+
<DefineConstants>$(DefineConstants);COMPLEX_TYPES;PRIMITIVE_COLLECTIONS;USE_FIND_COMPLEX_PROPERTY_FIX;</DefineConstants>
77
<TargetFramework>net8.0</TargetFramework>
88
</PropertyGroup>
99

src/Thinktecture.Runtime.Extensions.EntityFrameworkCore9/Thinktecture.Runtime.Extensions.EntityFrameworkCore9.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<PropertyGroup>
44
<Description>Extends Entity Framework Core to support some components from Thinktecture.Runtime.Extensions.</Description>
55
<PackageTags>smart-enum;value-object;discriminated-union;EntityFrameworkCore</PackageTags>
6-
<DefineConstants>$(DefineConstants);COMPLEX_TYPES;USE_FIND_COMPLEX_PROPERTY_FIX;</DefineConstants>
6+
<DefineConstants>$(DefineConstants);COMPLEX_TYPES;PRIMITIVE_COLLECTIONS;USE_FIND_COMPLEX_PROPERTY_FIX;</DefineConstants>
77
<TargetFramework>net8.0</TargetFramework>
88
</PropertyGroup>
99

test/Thinktecture.Runtime.Extensions.EntityFrameworkCore.Tests.Sources/EntityFrameworkCore/ValueConversion/ValueObjectValueConverterFactoryTests.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,14 @@ public async Task Should_write_and_read_enums_and_value_types()
3939
Boundary = Boundary.Create(10, 20),
4040
BoundaryWithCustomError = BoundaryWithCustomError.Create(11, 21),
4141
BoundaryWithCustomFactoryNames = BoundaryWithCustomFactoryNames.Get(11, 21),
42-
IntBasedReferenceValueObjectWitCustomFactoryName = IntBasedReferenceValueObjectWithCustomFactoryNames.Get(1)
42+
IntBasedReferenceValueObjectWitCustomFactoryName = IntBasedReferenceValueObjectWithCustomFactoryNames.Get(1),
43+
#if PRIMITIVE_COLLECTIONS
44+
CollectionOfIntBasedReferenceValueObject =
45+
[
46+
IntBasedReferenceValueObject.Create(1),
47+
IntBasedReferenceValueObject.Create(2)
48+
]
49+
#endif
4350
};
4451
_ctx.Add(entity);
4552
await _ctx.SaveChangesAsync();

test/Thinktecture.Runtime.Extensions.EntityFrameworkCore.Tests.Sources/TestEntities/TestEntity_with_Enum_and_ValueObjects.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using Microsoft.EntityFrameworkCore;
34
using Thinktecture.Runtime.Tests.TestEnums;
45
using Thinktecture.Runtime.Tests.TestValueObjects;
@@ -22,6 +23,10 @@ public class TestEntity_with_Enum_and_ValueObjects
2223
public required StringBasedStructValueObject StringBasedStructValueObject { get; set; }
2324
public StringBasedReferenceValueObjectWithCustomError? StringBasedReferenceValueObjectWithCustomError { get; set; }
2425

26+
#if PRIMITIVE_COLLECTIONS
27+
public List<IntBasedReferenceValueObject> CollectionOfIntBasedReferenceValueObject { get; set; } = [];
28+
#endif
29+
2530
public Boundary? Boundary { get; set; }
2631
public BoundaryWithCustomError? BoundaryWithCustomError { get; set; }
2732
public BoundaryWithCustomFactoryNames? BoundaryWithCustomFactoryNames { get; set; }
@@ -37,6 +42,10 @@ is ValueConverterRegistration.EntityConfiguration
3742

3843
modelBuilder.Entity<TestEntity_with_Enum_and_ValueObjects>(builder =>
3944
{
45+
#if PRIMITIVE_COLLECTIONS
46+
var primitiveCollectionBuilder = builder.PrimitiveCollection(e => e.CollectionOfIntBasedReferenceValueObject);
47+
#endif
48+
4049
if (valueConverterRegistration == ValueConverterRegistration.PropertyConfiguration)
4150
{
4251
builder.Property(e => e.SmartEnum_IntBased).HasThinktectureValueConverter();
@@ -50,6 +59,10 @@ is ValueConverterRegistration.EntityConfiguration
5059
builder.Property(e => e.StringBasedReferenceValueObjectWithCustomError).HasThinktectureValueConverter();
5160

5261
builder.Property(e => e.IntBasedReferenceValueObjectWitCustomFactoryName).HasThinktectureValueConverter();
62+
63+
#if PRIMITIVE_COLLECTIONS
64+
primitiveCollectionBuilder.HasThinktectureValueConverter(true);
65+
#endif
5366
}
5467

5568
builder.OwnsOne(e => e.Boundary, navigationBuilder =>

test/Thinktecture.Runtime.Extensions.EntityFrameworkCore8.Tests/Thinktecture.Runtime.Extensions.EntityFrameworkCore8.Tests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<DefineConstants>$(DefineConstants);COMPLEX_TYPES</DefineConstants>
4+
<DefineConstants>$(DefineConstants);COMPLEX_TYPES;PRIMITIVE_COLLECTIONS;</DefineConstants>
55
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
66
</PropertyGroup>
77

0 commit comments

Comments
 (0)