Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<!-- Properties related to build/pack -->
<IsPackable>false</IsPackable>
<Version>10.0.8-pre02</Version>
<Version>10.0.8-pre03</Version>
<MapsterPluginsTFMs>netstandard2.0;net10.0;net9.0;net8.0</MapsterPluginsTFMs>
<MapsterTFMs>netstandard2.0;net10.0;net9.0;net8.0</MapsterTFMs>
<MapsterEFCoreTFMs>net10.0;net9.0;net8.0</MapsterEFCoreTFMs>
Expand Down
84 changes: 36 additions & 48 deletions src/Mapster/Adapters/RecordTypeAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@
private ClassMapping? ClassConverterContext;
protected override int Score => -149;
protected override bool UseTargetValue => false;

private List<MemberMapping> SkipIgnoreNullValuesMemberMap = new List<MemberMapping>();

protected override bool CanMap(PreCompileArgument arg)
{
return arg.DestinationType.IsRecordType();
Expand All @@ -36,8 +33,6 @@
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)
Expand All @@ -53,7 +48,7 @@
}


return RecordInlineExpression(source, destination, arg, installExpr); // Activator field when not include in public ctor

Check warning on line 51 in src/Mapster/Adapters/RecordTypeAdapter.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference return.
}

private Expression? RecordInlineExpression(Expression source, Expression? destination, CompileArgument arg, Expression installExpr)
Expand All @@ -78,7 +73,6 @@
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;
Expand All @@ -88,30 +82,27 @@

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));

Check warning on line 99 in src/Mapster/Adapters/RecordTypeAdapter.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.
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
Expand Down Expand Up @@ -154,7 +145,7 @@
contructorMembers.Any(x => string.Equals(x.Name, member.Name, StringComparison.InvariantCultureIgnoreCase)))
continue;

lines.Add(Expression.Bind((MemberInfo)member.Info, Expression.MakeMemberAccess(destination, (MemberInfo)member.Info)));

Check warning on line 148 in src/Mapster/Adapters/RecordTypeAdapter.cs

View workflow job for this annotation

GitHub Actions / build

Converting null literal or possible null value to non-nullable type.

Check warning on line 148 in src/Mapster/Adapters/RecordTypeAdapter.cs

View workflow job for this annotation

GitHub Actions / build

Converting null literal or possible null value to non-nullable type.
}

return lines;
Expand All @@ -171,29 +162,6 @@

var lines = new List<Expression>();

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)
Expand All @@ -203,7 +171,6 @@
|| 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);
Expand All @@ -225,9 +192,9 @@

if (arg.MapType == MapType.MapToTarget)
{
var var2Param = ClassConverterContext.Members.Where(x => x.DestinationMember.Name == member.DestinationMember.Name).FirstOrDefault();

Check warning on line 195 in src/Mapster/Adapters/RecordTypeAdapter.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.

Expression destMemberVar2 = var2Param.DestinationMember.GetExpression(var2Param.Destination);

Check warning on line 197 in src/Mapster/Adapters/RecordTypeAdapter.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference argument for parameter 'source' in 'Expression IMemberModelEx.GetExpression(Expression source)'.
var ParamLambdaVar2 = destMemberVar2;
if(member.DestinationMember.Type.IsRecordType())
ParamLambdaVar2 = arg.Context.Config.CreateMapInvokeExpressionBody(member.Getter.Type, member.DestinationMember.Type, destMemberVar2);
Expand Down Expand Up @@ -291,6 +258,27 @@
}

}
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();
Expand Down
Loading