From de287c57fab95b8a1365b864784dd4802a51fddd Mon Sep 17 00:00:00 2001 From: alihut Date: Wed, 19 Aug 2026 13:49:37 +0300 Subject: [PATCH 1/2] fix: apply IgnoreIf to record properties outside the primary constructor --- .../WhenIgnoringConditionally.cs | 43 +++++++++++++++++++ src/Mapster/Adapters/RecordTypeAdapter.cs | 22 ++++++++++ 2 files changed, 65 insertions(+) diff --git a/src/Mapster.Tests/WhenIgnoringConditionally.cs b/src/Mapster.Tests/WhenIgnoringConditionally.cs index 9014d133..b8292609 100644 --- a/src/Mapster.Tests/WhenIgnoringConditionally.cs +++ b/src/Mapster.Tests/WhenIgnoringConditionally.cs @@ -172,6 +172,43 @@ public void IgnoreIf_Apply_To_RecordType() dto.Name.ShouldBeNull(); } + // Regression test for https://github.com/MapsterMapper/Mapster/issues/1007 + // Unlike SimpleRecord above (which maps every member through the primary + // constructor), NativeRecord is a real C# `record` whose Name property is + // NOT part of the primary constructor — it's a plain settable auto-property. + // Members mapped that way go through RecordTypeAdapter.RecordInlineExpression, + // a separate code path from constructor-argument mapping, which used to + // ignore member.Ignore.Condition entirely. + [TestMethod] + public void IgnoreIf_Apply_To_RecordType_Property_Not_In_Constructor_Map() + { + TypeAdapterConfig.NewConfig() + .IgnoreIf((src, dest) => src.Name == "TestName", dest => dest.Name) + .Compile(); + + var poco = new SimplePoco { Id = 1, Name = "TestName" }; + var dto = TypeAdapter.Adapt(poco); + + dto.Id.ShouldBe(1); + dto.Name.ShouldBeNull(); + } + + [TestMethod] + public void IgnoreIf_Apply_To_RecordType_Property_Not_In_Constructor_MapToTarget() + { + TypeAdapterConfig.NewConfig() + .IgnoreIf((src, dest) => src.Name == "TestName", dest => dest.Name) + .Compile(); + + var poco = new SimplePoco { Id = 1, Name = "TestName" }; + var dto = new NativeRecord { Id = 999, Name = "DtoName" }; + + var result = TypeAdapter.Adapt(poco, dto); + + result.Id.ShouldBe(1); + result.Name.ShouldBe("DtoName"); + } + #endregion @@ -202,6 +239,12 @@ public SimpleRecord(int id, string name) } } + public record NativeRecord + { + public int Id { get; set; } + public string Name { get; set; } + } + #endregion } diff --git a/src/Mapster/Adapters/RecordTypeAdapter.cs b/src/Mapster/Adapters/RecordTypeAdapter.cs index 63c32747..ab318caa 100644 --- a/src/Mapster/Adapters/RecordTypeAdapter.cs +++ b/src/Mapster/Adapters/RecordTypeAdapter.cs @@ -103,6 +103,28 @@ protected override Expression CreateInstantiationExpression(Expression source, E } } + // IgnoreIf(...) support — unlike ClassAdapter (which drops the whole + // member statement into an `if (!condition) { ... }` block), record + // members are bound inline inside a MemberInit, so the condition is + // expressed as a ternary: keep the computed value when the condition + // is false, otherwise fall back to whatever the member should be left + // as (the existing destination value for MapToTarget, or the type's + // default value when constructing a brand-new instance). + if (arg.MapType != MapType.Projection && member.Ignore.Condition != null) + { + var conditionDestination = destination ?? arg.DestinationType.CreateDefault(); + var conditionBody = member.Ignore.IsChildPath + ? member.Ignore.Condition.Body + : member.Ignore.Condition.Apply(arg.MapType, source, conditionDestination); + var notIgnored = ExpressionEx.Not(conditionBody); + + var fallback = arg.MapType == MapType.MapToTarget && destination != null + ? member.DestinationMember.GetExpression(destination) + : member.DestinationMember.Type.CreateDefault(); + + adapt = Expression.Condition(notIgnored, adapt, fallback); + } + //special null property check for projection //if we don't set null to property, EF will create empty object //except collection type & complex type which cannot be null From 1f3fe109d314968387992c87a9cb115b5b11af9f Mon Sep 17 00:00:00 2001 From: DocSvartz Date: Wed, 19 Aug 2026 17:46:02 +0500 Subject: [PATCH 2/2] chore: Bump version to v10.0.12 --- src/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 7b0f4082..99ef89c6 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -2,7 +2,7 @@ false - 10.0.11 + 10.0.12 netstandard2.0;net10.0;net9.0;net8.0 netstandard2.0;net10.0;net9.0;net8.0 net10.0;net9.0;net8.0