diff --git a/src/Directory.Build.props b/src/Directory.Build.props index ea0770e0..1b0404e4 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -2,7 +2,7 @@ false - 10.0.8-pre02 + 10.0.8-pre03 netstandard2.0;net10.0;net9.0;net8.0 netstandard2.0;net10.0;net9.0;net8.0 net10.0;net9.0;net8.0 diff --git a/src/Mapster/Adapters/RecordTypeAdapter.cs b/src/Mapster/Adapters/RecordTypeAdapter.cs index 659da39c..55d20b1f 100644 --- a/src/Mapster/Adapters/RecordTypeAdapter.cs +++ b/src/Mapster/Adapters/RecordTypeAdapter.cs @@ -14,9 +14,6 @@ internal class RecordTypeAdapter : ClassAdapter private ClassMapping? ClassConverterContext; protected override int Score => -149; protected override bool UseTargetValue => false; - - private List SkipIgnoreNullValuesMemberMap = new List(); - protected override bool CanMap(PreCompileArgument arg) { return arg.DestinationType.IsRecordType(); @@ -36,8 +33,6 @@ protected override Expression CreateInlineExpression(Expression source, CompileA protected override Expression CreateInstantiationExpression(Expression source, Expression? destination, CompileArgument arg) { //new TDestination(src.Prop1, src.Prop2) - - SkipIgnoreNullValuesMemberMap.Clear(); Expression installExpr; if (arg.GetConstructUsing() != null || arg.Settings.MapToConstructor != null || arg.DestinationType == null) @@ -78,7 +73,6 @@ protected override Expression CreateInstantiationExpression(Expression source, E lines.AddRange(memberInit.Bindings); foreach (var member in members) { - if (!arg.Settings.Resolvers.Any(r => r.DestinationMemberName == member.DestinationMember.Name) && contructorMembers.Any(x => string.Equals(x.Name, member.DestinationMember.Name, StringComparison.InvariantCultureIgnoreCase))) continue; @@ -88,30 +82,27 @@ protected override Expression CreateInstantiationExpression(Expression source, E var adapt = CreateAdaptExpression(member.Getter, member.DestinationMember.Type, arg, member); - if (arg.Settings.IgnoreNullValues == true && member.Getter.CanBeNull()) // add IgnoreNullValues support + if (arg.MapType != MapType.Projection && arg.Settings.IgnoreNullValues == true && member.Getter.CanBeNull()) // add IgnoreNullValues support { - if (arg.MapType != MapType.MapToTarget) - { - SkipIgnoreNullValuesMemberMap.Add(member); - continue; - } + if(arg.MapType == MapType.Map) + continue; // skip to block handler - if (adapt is ConditionalExpression condEx) + if (arg.MapType == MapType.MapToTarget) { - if (condEx.Test is BinaryExpression { NodeType: ExpressionType.Equal } binEx && - binEx.Left == member.Getter && - binEx.Right is ConstantExpression { Value: null }) - adapt = condEx.IfFalse; + if (adapt is ConditionalExpression condEx) + { + if (condEx.Test is BinaryExpression { NodeType: ExpressionType.Equal } binEx && + binEx.Left == member.Getter && + binEx.Right is ConstantExpression { Value: null }) + adapt = condEx.IfFalse; + } + var destinationCompareNull = Expression.Equal(destination, Expression.Constant(null, destination.Type)); + var sourceCondition = Expression.NotEqual(member.Getter, Expression.Constant(null, member.Getter.Type)); + var destinationCanbeNull = Expression.Condition(destinationCompareNull, member.DestinationMember.Type.CreateDefault(), member.DestinationMember.GetExpression(destination)); + adapt = Expression.Condition(sourceCondition, adapt, destinationCanbeNull); } - var destinationCompareNull = Expression.Equal(destination, Expression.Constant(null, destination.Type)); - var sourceCondition = Expression.NotEqual(member.Getter, Expression.Constant(null, member.Getter.Type)); - var destinationCanbeNull = Expression.Condition(destinationCompareNull, member.DestinationMember.Type.CreateDefault(), member.DestinationMember.GetExpression(destination)); - adapt = Expression.Condition(sourceCondition, adapt, destinationCanbeNull); } - - - //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 @@ -171,29 +162,6 @@ protected override Expression CreateBlockExpression(Expression source, Expressio var lines = new List(); - if (arg.MapType != MapType.MapToTarget) - { - foreach (var member in SkipIgnoreNullValuesMemberMap) - { - - var adapt = CreateAdaptExpression(member.Getter, member.DestinationMember.Type, arg, member); - - if (adapt is ConditionalExpression condEx) - { - if (condEx.Test is BinaryExpression { NodeType: ExpressionType.Equal } binEx && - binEx.Left == member.Getter && - binEx.Right is ConstantExpression { Value: null }) - adapt = condEx.IfFalse; - } - adapt = member.DestinationMember.SetExpression(destination, adapt); - var sourceCondition = Expression.NotEqual(member.Getter, Expression.Constant(null, member.Getter.Type)); - - - lines.Add(Expression.IfThen(sourceCondition, adapt)); - } - } - - foreach (var member in members) { if (member.DestinationMember.SetterModifier == AccessModifier.None && member.UseDestinationValue) @@ -203,7 +171,6 @@ protected override Expression CreateBlockExpression(Expression source, Expressio || member.DestinationMember.Type.IsMapsterPrimitive() || member.DestinationMember.Type.IsRecordType()) { - Expression adapt; if (member.DestinationMember.Type.IsRecordType()) adapt = arg.Context.Config.CreateMapInvokeExpressionBody(member.Getter.Type, member.DestinationMember.Type, member.Getter); @@ -291,6 +258,27 @@ protected override Expression CreateBlockExpression(Expression source, Expressio } } + else + { + // IgnoreNullValues to Map type mapping + if(arg.MapType == MapType.Map && arg.Settings.IgnoreNullValues == true && member.Getter.CanBeNull()) + { + var adapt = CreateAdaptExpression(member.Getter, member.DestinationMember.Type, arg, member); + + if (adapt is ConditionalExpression condEx) + { + if (condEx.Test is BinaryExpression { NodeType: ExpressionType.Equal } binEx && + binEx.Left == member.Getter && + binEx.Right is ConstantExpression { Value: null }) + adapt = condEx.IfFalse; + } + adapt = member.DestinationMember.SetExpression(destination, adapt); + var sourceCondition = Expression.NotEqual(member.Getter, Expression.Constant(null, member.Getter.Type)); + + + lines.Add(Expression.IfThen(sourceCondition, adapt)); + } + } } return lines.Count > 0 ? (Expression)Expression.Block(lines) : Expression.Empty();