Documento per tracciare le funzionalità implementate e testate.
Ogni casella rappresenta una combinazione che DEVE essere supportata e testata.
Last Updated : 2026-05-31
Test Summary : all tests green — see Pragmatic.Mapping.Tests and Pragmatic.Mapping.EFCore.Tests (243 + 25 passing as of 2026-05-31)
Symbol Meaning ✅ Implemented & Tested ⚠️ Implemented, needs fix ❌ Not implemented 🔲 Planned
Type Kind FromEntity ToEntity Projection Test File class✅ ✅ ✅ NullableAndNestedGeneratorTests.PartialClass_GeneratesCorrectlyrecord✅ ✅ ✅ BasicMappingGeneratorTestsstruct✅ 🔲 🔲 NullableAndNestedGeneratorTests.PartialStruct_GeneratesCorrectlyrecord struct✅ 🔲 🔲 BasicMappingGeneratorTests.MapFrom_RecordStruct_GeneratesCorrectly
Source Type Kind Support Test class✅ All basic tests record✅ - struct✅ NullableAndNestedGeneratorTests.PartialStruct_GeneratesCorrectlyrecord struct✅ -
Note : Null check skipped for value types (structs can’t be null).
Type Direct Mapping Test int✅ BasicMappingGeneratorTestsint?✅ NullableAndNestedGeneratorTests.NullableInt_MapsDirectlystring✅ Multiple tests string?✅ NullableAndNestedGeneratorTests.NullableString_MapsDirectlydecimal✅ NullableAndNestedGeneratorTests.PartialClass_GeneratesCorrectlyDateTime✅ - DateTime?✅ NullableAndNestedGeneratorTests.NullableDateTime_MapsDirectlyGuid✅ - Guid?✅ TypeConversionGeneratorTests.NullableGuid_MapsDirectlyDateOnly✅ TypeConversionGeneratorTests.DateOnly_MapsDirectlyTimeOnly✅ TypeConversionGeneratorTests.DateOnly_MapsDirectlyDateOnly?✅ TypeConversionGeneratorTests.NullableDateOnly_MapsDirectlyTimeOnly?✅ TypeConversionGeneratorTests.NullableDateOnly_MapsDirectlyenum✅ TypeConversionGeneratorTests.Enum_SameType_MapsDirectlyenum?✅ TypeConversionGeneratorTests.NullableEnum_MapsDirectly
Collection Type Simple Element DTO Element Test T[]✅ ✅ CollectionMappingGeneratorTests.ArrayOfInt, ArrayOfDtoList<T>✅ ✅ CollectionMappingGeneratorTests.ListOfString, ListOfDtoList<T>?✅ ✅ NullableListOfNullableInt, NullableListOfNullableNestedDtoIList<T>✅ ✅ CollectionMappingGeneratorTests.IListOfIntICollection<T>✅ ✅ CollectionMappingGeneratorTests.ICollectionOfIntIEnumerable<T>✅ ✅ CollectionMappingGeneratorTests.IEnumerableOfIntIReadOnlyList<T>✅ 🔲 CollectionMappingGeneratorTests.IReadOnlyListOfIntIReadOnlyCollection<T>✅ 🔲 CollectionMappingGeneratorTests.IReadOnlyCollectionOfIntHashSet<T>✅ 🔲 CollectionMappingGeneratorTests.HashSetOfInt
Scenario Status Test Single non-nullable DTO ✅ NullableAndNestedGeneratorTests.NestedDto_MapsWithFromEntitySingle nullable DTO ✅ NullableAndNestedGeneratorTests.NullableNestedDto_HandlesNullSafelyArray of DTO ✅ NullableAndNestedGeneratorTests.ArrayOfNestedDto_MapsEachElementList of DTO ✅ CollectionMappingGeneratorTests.ListOfDto_MapsEachElementList of nullable DTO ✅ NullableAndNestedGeneratorTests.NullableListOfNullableNestedDto_HandlesCorrectly
Implementation : Uses SymbolDisplayFormat.FullyQualifiedFormat for type names to avoid namespace resolution issues.
Dictionary Type Simple Value DTO Value Test Dictionary<K,V>✅ ✅ CollectionMappingGeneratorTests.DictionaryStringInt, TypeConversionGeneratorTests.DictionaryWithDtoValueIDictionary<K,V>🔲 🔲 - IReadOnlyDictionary<K,V>🔲 🔲 -
Conversion Status Test int → long✅ TypeConversionGeneratorTests.IntToLong_ImplicitConversionint → decimal✅ TypeConversionGeneratorTests.IntToDecimal_ImplicitConversionint? → int (no default)⚠️ CS0266 TypeConversionGeneratorTests.NullableIntToInt_WithoutDefault_ShouldCompileint? → int (with default)✅ AdvancedMappingGeneratorTests.MapProperty_WithDefault_UsesDefaultWhenNull
Note : C# implicit conversions (widening) work automatically. Nullable → Non-nullable requires [MapProperty(Default=)].
Conversion Status Generated Code Test int → string✅ .ToString()TypeConversionGeneratorTests.IntToStringstring → int✅ int.Parse()TypeConversionGeneratorTests.StringToIntenum → string✅ .ToString()TypeConversionGeneratorTests.EnumToStringstring → enum✅ Enum.Parse<T>()TypeConversionGeneratorTests.StringToEnumGuid → string✅ .ToString()TypeConversionGeneratorTests.GuidToStringstring → Guid✅ Guid.Parse()TypeConversionGeneratorTests.StringToGuidDateTime → DateOnly✅ DateOnly.FromDateTime()TypeConversionGeneratorTests.DateTimeToDateOnlyDateOnly → DateTime✅ .ToDateTime(TimeOnly.MinValue)TypeConversionGeneratorTests.DateOnlyToDateTimeDateTime → TimeOnly✅ TimeOnly.FromDateTime()TypeConversionGeneratorTests.DateTimeToTimeOnlydecimal → string✅ .ToString()TypeConversionGeneratorTests.DecimalToStringstring → decimal✅ decimal.Parse()TypeConversionGeneratorTests.StringToDecimalbool → string✅ .ToString()TypeConversionGeneratorTests.BoolToStringstring → bool✅ bool.Parse()TypeConversionGeneratorTests.StringToBoolDateTime → string✅ .ToString()TypeConversionGeneratorTests.DateTimeToStringstring → DateTime✅ DateTime.Parse()TypeConversionGeneratorTests.StringToDateTimestring → DateOnly✅ DateOnly.Parse()TypeConversionGeneratorTests.StringToDateOnlystring → TimeOnly✅ TimeOnly.Parse()TypeConversionGeneratorTests.StringToTimeOnly
Implementation : Generator detects source/target type mismatch and applies known conversion patterns automatically.
Nullable variants also supported (e.g., int? → string, string → int?).
Source → Target Status Test List<T> → T[]✅ TypeConversionGeneratorTests.ListToArray_ConversionT[] → List<T>✅ TypeConversionGeneratorTests.ArrayToList_ConversionIEnumerable<T> → List<T>✅ TypeConversionGeneratorTests.IEnumerableToList_ConversionList<T> → IEnumerable<T>✅ TypeConversionGeneratorTests.ListToIEnumerable_ConversionList<T> → HashSet<T>✅ TypeConversionGeneratorTests.ListToHashSet_ConversionT[] → IReadOnlyList<T>✅ TypeConversionGeneratorTests.ArrayToIReadOnlyList_Conversion
Attribute Status Test [MapFrom<T>]✅ All FromEntity tests [MapTo<T>]✅ AdvancedMappingGeneratorTests.MapTo_*[MapProperty]✅ AdvancedMappingGeneratorTests.MapProperty_*[MapProperty(Default=)]✅ AdvancedMappingGeneratorTests.MapProperty_WithDefault_UsesDefaultWhenNull[MapIgnore]✅ AdvancedMappingGeneratorTests.MapIgnore_*[MapConverter<T>]✅ AdvancedMappingGeneratorTests.Converter_*[MapConstructor]✅ AdvancedMappingGeneratorTests.MapTo_UsesConstructor[GenerateProjection]✅ ProjectionGeneratorTests.*
Strategy Status Test Direct name match ✅ All basic tests Case-insensitive match ✅ - Flattening (AddressCity → Address.City) ✅ AdvancedMappingGeneratorTests.Flattening_*Concatenation (FullName → FirstName + LastName) ✅ BasicMappingGeneratorTests.MapFrom_WithFullNameConventionExplicit path via [MapProperty] ✅ AdvancedMappingGeneratorTests.MapProperty_*
Feature Status Test ID property exclusion in ToEntity ✅ AdvancedMappingGeneratorTests.MapTo_ExcludesIdByDefaultInit-only properties ✅ - Required properties ✅ - Circular reference detection ✅ - Null safety ✅ NullableAndNestedGeneratorTests.*
Method Status Struct Support Test FromEntity(entity)✅ ✅ All FromEntity tests ToEntity()✅ 🔲 MapTo tests Projection✅ 🔲 ProjectionGeneratorTests
Note : ApplyTo(entity) is generated by Pragmatic.Mapping for DTOs marked with [MapTo<T>] (updates an existing entity, partial-update semantics). It is suppressed only when the DTO also carries [Patch<T>] or [Mutation<T>], in which case the respective generator owns the update path.
Hook Status Test partial void BeforeMapping()✅ - partial void CustomizeMapping()✅ - MappingContext struct✅ -
DTO Accessibility Support Extensions Class Test public✅ public staticAll basic tests internal✅ internal staticAdvancedMappingGeneratorTests.MapFrom_InternalClass_GeneratesInternalMethodsprivate (nested)🔲 - -
Bug Status Fix Struct source + Ensure.ThrowIfNull✅ FIXED Skip null check for value types Nullable DTO type name includes ?✅ FIXED Use SymbolDisplayFormat.FullyQualifiedFormat List<string> treated as DTO collection✅ FIXED Check IsElementSimple in AnalyzeNestedDto Extensions class ignores accessibility✅ FIXED Added ParseAccessibility() in MappingExtensionsTemplate [MapProperty(Default=)] not implemented✅ FIXED Added fallback resolution by property name when only Default is specified
Issue Status Fix Test [MapProperty(Format=)] for non-DateTime✅ FIXED Added format support to GenerateNumericToString and GenerateToString AdvancedMappingGeneratorTests.MapProperty_WithFormat_*[MapProperty] + [MapConverter] together✅ FIXED Moved converter check before MapProperty check, passed converter to CreateExplicitMapping AdvancedMappingGeneratorTests.MapProperty_WithMapConverter_*
Test File Tests Passing Failing BasicMappingGeneratorTests7 7 0 AdvancedMappingGeneratorTests16 16 0 CollectionMappingGeneratorTests9 9 0 ProjectionGeneratorTests5 5 0 NullableAndNestedGeneratorTests9 9 0 TypeConversionGeneratorTests51 51 0 AutomaticConversionGeneratorTests12 12 0 AutoDefaultGeneratorTests12 12 0 DiagnosticTests4 4 0 TOTAL 125 125 0
Note : EF Core integration tests use TestContainers with PostgreSQL.
Sample File Features Demonstrated BasicMappingSampleFromEntity, extension methods, collection mapping, FullName concatenation, flattening NestedMappingSampleNested DTOs, collection of DTOs, flattened DTO BidirectionalMappingSampleMapFrom + MapTo, ToEntity() StructMappingSamplerecord struct, zero-allocation, Projection ProjectionSampleGenerateProjection, Expression<Func<T,TDto>> TypeConversionSampleToString, Parse, DateTime↔DateOnly, Dictionary with DTOs, Inheritance NullableAndAdvancedSampleAuto-default, Collection type conversions, Circular references, DateOnly→DateTime TypeCombinationsSampleclass→class, class→record, record→record, record→class, MapIgnore AdvancedAttributesSampleMapIgnore, MapConverter, MapProperty(path), MapProperty(Format)
Core source generator (FromEntity, ToEntity, Projection)
All property types (simple, nullable, collections, nested DTOs)
Property resolution (direct match, flattening, concatenation)
MapProperty with Default value
MapIgnore, MapConverter attributes
EF Core integration package with extension methods
Comprehensive samples (Basic, Nested, Bidirectional, Struct, Projection, TypeConversion)
README documentation
P0: Auto-default for primitives (GetValueOrDefault, ?? "")
P1: Type conversions (ToString, Parse, enum↔string, Guid↔string)
P2: DateTime conversions (DateTime↔DateOnly/TimeOnly)
P3: Dictionary with DTO values, Inheritance mapping
Feature Description Status Auto-default for primitives int? → int uses GetValueOrDefault(), string? → string uses ?? ""✅ Implemented Auto-default in Projection Uses ?? 0, ?? "", ?? Guid.Empty for EF Core Expression Tree compatibility ✅ Implemented
Feature Description Status Test ToString conversions int → string via .ToString()✅ TypeConversionGeneratorTests.IntToStringEnum → string Status.Active → "Active"✅ TypeConversionGeneratorTests.EnumToStringParse conversions string → int via int.Parse()✅ TypeConversionGeneratorTests.StringToIntGuid ↔ string Guid.ToString() / Guid.Parse()✅ TypeConversionGeneratorTests.GuidToString/StringToGuid
Feature Description Status Test DateTime → DateOnly DateOnly.FromDateTime()✅ TypeConversionGeneratorTests.DateTimeToDateOnlyDateTime → TimeOnly TimeOnly.FromDateTime()✅ TypeConversionGeneratorTests.DateTimeToTimeOnlyDateOnly → DateTime .ToDateTime(TimeOnly.MinValue)✅ TypeConversionGeneratorTests.DateOnlyToDateTimeString ↔ decimal Parse/ToString ✅ TypeConversionGeneratorTests.StringToDecimal/DecimalToString
Feature Description Status Test Dictionary with DTO values Dictionary<string, CategoryDto>✅ TypeConversionGeneratorTests.DictionaryWithDtoValueInheritance mapping Base → Derived DTO properties ✅ TypeConversionGeneratorTests.InheritedPropertiesInterface-based DTOs IUserDto🔲 Future
Scenario Category Test File Status Same-name property mapping Basic BasicMappingGeneratorTests✅ Different-name property mapping Advanced AdvancedMappingGeneratorTests✅ Custom converter Advanced AdvancedMappingGeneratorTests✅ Nested DTO mapping Nested NullableAndNestedGeneratorTests✅ Collection of DTOs Collection CollectionMappingGeneratorTests✅
Scenario Test Status Non-partial class skips generation DiagnosticTests.NonPartialClass_SkipsGeneration✅ Partial class generates correctly DiagnosticTests.PartialClass_GeneratesCorrectly✅ Unmatched property uses default DiagnosticTests.UnmatchedProperty_GeneratesWithDefault✅ Invalid MapProperty path DiagnosticTests.MapProperty_WithInvalidPath_CompilesButUnmapped✅ [GenerateProjection] without [MapFrom] DiagnosticTests.GenerateProjection_WithoutMapFrom_SkipsProjection✅ [MapIgnore] takes precedence DiagnosticTests.MapIgnore_TakesPrecedence_OverMapProperty✅ Nested DTO with [MapFrom] DiagnosticTests.NestedDto_WithMapFrom_GeneratesCorrectly✅ Collection with simple elements DiagnosticTests.Collection_WithSimpleElements_MapsDirectly✅ Struct source skips null check DiagnosticTests.StructSource_SkipsNullCheck✅ Class source includes null check DiagnosticTests.ClassSource_IncludesNullCheck✅ MapTo excludes ID by default DiagnosticTests.MapTo_ExcludesIdByDefault✅ Internal class generates internal extensions DiagnosticTests.InternalClass_GeneratesInternalExtensions✅ Empty DTO generates minimal DiagnosticTests.EmptyDto_GeneratesMinimalMapping✅ Multiple [MapFrom] causes error DiagnosticTests.MultipleMapFrom_CausesDuplicateAttributeError✅ Bidirectional mapping DiagnosticTests.MapFrom_And_MapTo_OnSameType_GeneratesBothMethods✅
When using EF Core, navigation properties require explicit Include() calls when using FromEntity():
// ⚠️ PROBLEM: Lazy loading or null navigation properties
var users = await _db.Users. ToListAsync ();
var dtos = users. ToUserDto (); // Orders will be null/empty!
// ✅ SOLUTION 1: Manual Include
var users = await _db.Users
var dtos = users. ToUserDto ();
// ✅ SOLUTION 2: Use Projection (BEST - optimized SQL)
var dtos = await _db.Users
. Select (UserDto.Projection)
Feature Status Description SelectDto(projection)✅ Projects query using expression ToListDtoAsync(projection)✅ Async projection to list FirstOrDefaultDtoAsync(projection)✅ Async single item projection SingleOrDefaultDtoAsync(projection)✅ Async single-or-default projection ToArrayDtoAsync(projection)✅ Async projection to array ToPagedDtoAsync(projection, page, size)✅ Paginated projection with metadata ToSliceDtoAsync(projection, offset, limit)✅ Offset/limit projection
// Projection-based (generates optimized SQL)
var dtos = await _db.Users
. ToListDtoAsync (UserDto.Projection);
var page = await _db.Users
. ToPagedDtoAsync (UserDto.Projection, pageNumber : 1 , pageSize : 20 );
// page.Items, page.TotalCount, page.TotalPages, page.HasNextPage, etc.
Feature Status Description RequiredIncludes<TDto>()🔲 Planned Returns Include chain for FromEntity WithRequiredIncludes<TDto>()🔲 Planned Applies required includes to query
Note : Auto-Include features require DomainEntity metadata (not yet implemented).