Skip to content

Commit b0dda70

Browse files
authored
chore: Merge pull request #971 from leno23/fix/projectto-nullable-nav-record-898-dev
fix: ProjectToType nullable navigation to record DTO ctor (#898)
2 parents 03d7edc + a0aee31 commit b0dda70

3 files changed

Lines changed: 28 additions & 16 deletions

File tree

src/Mapster.Tests/WhenAddCtorNullablePropagation.cs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
using Mapster.Tests.Classes;
2-
using Microsoft.VisualStudio.TestTools.UnitTesting;
1+
using Microsoft.VisualStudio.TestTools.UnitTesting;
2+
using Shouldly;
33
using System.Collections.Generic;
44
using System.Linq;
55

@@ -15,14 +15,25 @@ public class WhenAddCtorNullablePropagation
1515
[TestMethod]
1616
public void NullablePropagationFromCtorWorking()
1717
{
18-
var source = new List<OrderEntity898>();
18+
var source = new List<OrderEntity898>
19+
{
20+
new() { Id = 1, Cod = new OrderCodEntity898 { Value = 42L } },
21+
new() { Id = 2, Cod = null },
22+
};
1923

20-
source.Add(new OrderEntity898() { Id = 1, Cod = new OrderCodEntity898 { Value = 42L } });
21-
source.Add(new OrderEntity898() { Id = 2, Cod = null });
22-
23-
var str = new OrderEntity898() { Id = 1, Cod = new OrderCodEntity898 { Value = 42L } }.BuildAdapter().CreateProjectionExpression<OrderDto898>();
24+
Should.NotThrow(() =>
25+
{
26+
source.AsQueryable().BuildAdapter().CreateProjectionExpression<OrderDto898>();
27+
});
2428

2529
var result = source.AsQueryable().ProjectToType<OrderDto898>().ToList();
30+
31+
result.Count.ShouldBe(2);
32+
result[0].Id.ShouldBe(1);
33+
result[0].Cod.ShouldNotBeNull();
34+
result[0].Cod!.Value.ShouldBe(42L);
35+
result[1].Id.ShouldBe(2);
36+
result[1].Cod.ShouldBeNull();
2637
}
2738

2839
}

src/Mapster/Adapters/BaseClassAdapter.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -218,9 +218,9 @@ protected Expression CreateInstantiationExpression(Expression source, ClassMappi
218218
var members = classConverter.Members;
219219

220220
var arguments = new List<Expression>();
221+
arg.Context.NullChecks.UnionWith(members.Where(x => x.Getter != null).Select(x => (x.Getter, arg)));
221222
foreach (var member in members)
222223
{
223-
arg.Context.NullChecks.UnionWith(members.Where(x=>x.Getter != null).Select(x=>(x.Getter,arg)));
224224
var parameterInfo = (ParameterInfo)member.DestinationMember.Info!;
225225
Expression defaultConst;
226226
Expression getter;
@@ -253,12 +253,13 @@ protected Expression CreateInstantiationExpression(Expression source, ClassMappi
253253
else
254254
{
255255

256-
if (member.Getter.CanBeNull() && member.DestinationMember.Type.IsAbstractOrNotPublicCtor()
257-
&& member.Ignore.Condition == null)
256+
if (member.Getter.CanBeNull() && member.Ignore.Condition == null
257+
&& (member.DestinationMember.Type.IsAbstractOrNotPublicCtor()
258+
|| member.DestinationMember.Type.UnwrapNullable().IsRecordType()))
258259
{
259260
var compareNull = Expression.Equal(member.Getter, Expression.Constant(null, member.Getter.Type));
260261
getter = Expression.Condition(ExpressionEx.Not(compareNull),
261-
CreateAdaptExpression(member.Getter, member.DestinationMember.Type, arg, member),
262+
CreateAdaptExpressionCore(member.Getter, member.DestinationMember.Type, arg, member),
262263
defaultConst);
263264
}
264265
else

src/Mapster/Utils/ExpressionEx.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -453,18 +453,18 @@ public static Expression ApplyNullPropagationFromCtor(this Expression getter, Ex
453453
Expression? condition = null;
454454
var current = getter;
455455
var checks = arg.Context.NullChecks
456-
.Where(x=> !object.ReferenceEquals(x.arg,arg))
457-
.Select(x=>x.param?.Type);
456+
.Where(x => !object.ReferenceEquals(x.arg, arg))
457+
.Select(x => x.param);
458458

459459
while (current != null)
460460
{
461461
Expression? compareNull = null;
462462

463463
if (current.CanBeNull() && current is not ParameterExpression)
464464
compareNull = Expression.NotEqual(current, Expression.Constant(null, current.Type));
465-
else if (current.CanBeNull() && current is ParameterExpression
466-
&& !checks.Contains(current.Type))
467-
compareNull = Expression.NotEqual(current, Expression.Constant(null, current.Type));
465+
else if (current.CanBeNull() && current is ParameterExpression param
466+
&& !checks.Contains(param))
467+
compareNull = Expression.NotEqual(param, Expression.Constant(null, param.Type));
468468

469469
if (compareNull != null)
470470
{

0 commit comments

Comments
 (0)