Skip to content

Commit 0be7cd1

Browse files
committed
fail not work
1 parent dab49b8 commit 0be7cd1

3 files changed

Lines changed: 38 additions & 78 deletions

File tree

src/Mapster/Adapters/BaseClassAdapter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ select fn(src, destinationMember, arg))
137137
}
138138
if (getter != null)
139139
{
140-
propertyModel.Getter = arg.MapType == MapType.Projection
140+
propertyModel.Getter = arg.MapType == MapType.Projection || ctorMapping
141141
? getter
142142
: getter.ApplyPropertyNullPropagation(arg, source);
143143
properties.Add(propertyModel);

src/Mapster/Utils/DirectParameterMemberFinder.cs

Lines changed: 34 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -4,118 +4,76 @@
44

55
public class DirectParameterMemberFinder : ExpressionVisitor
66
{
7+
private readonly bool _expression;
8+
79
private readonly Stack<bool> _isInsideParameterChain = new();
810
private readonly HashSet<Expression> _TargetParams;
911
public List<Expression> FoundMembers { get; } = new();
1012

11-
1213
public DirectParameterMemberFinder(params Expression[] targetParams)
1314
{
1415
_TargetParams = new HashSet<Expression>(targetParams);
1516
}
1617

17-
protected override Expression VisitParameter(ParameterExpression node)
18-
{
19-
_isInsideParameterChain.Push(true);
20-
var result = base.VisitParameter(node);
21-
_isInsideParameterChain.Pop();
22-
return result;
23-
}
18+
2419

2520
protected override Expression VisitMember(MemberExpression node)
2621
{
27-
if (node.Expression is ParameterExpression || _isInsideParameterChain.Any(x => x))
28-
{
29-
FoundMembers.Add(node);
30-
}
22+
var getParam = new GetParametr();
3123

32-
_isInsideParameterChain.Push(_isInsideParameterChain.Any(x => x));
33-
this.Visit(node.Expression);
34-
_isInsideParameterChain.Pop();
35-
return node;
36-
}
24+
var param = getParam.GetParam(node.Expression);
3725

38-
protected override Expression VisitIndex(IndexExpression node)
39-
{
40-
if (_isInsideParameterChain.Any(x => x))
41-
{
26+
if (_TargetParams.Contains(param))
4227
FoundMembers.Add(node);
43-
}
4428

45-
_isInsideParameterChain.Push(_isInsideParameterChain.Any(x => x));
46-
this.Visit(node.Object);
47-
foreach (var argument in node.Arguments)
48-
{
49-
this.Visit(argument);
50-
}
51-
_isInsideParameterChain.Pop();
5229
return node;
30+
5331
}
5432

33+
34+
5535
protected override Expression VisitUnary(UnaryExpression node)
5636
{
5737
if (node.NodeType == ExpressionType.Convert || node.NodeType == ExpressionType.ConvertChecked)
5838
{
59-
_isInsideParameterChain.Push(_isInsideParameterChain.Any(x => x));
39+
bool parentWasInChain = _isInsideParameterChain.Any(x => x);
40+
_isInsideParameterChain.Push(parentWasInChain);
6041
var result = base.VisitUnary(node);
6142
_isInsideParameterChain.Pop();
6243
return result;
6344
}
6445
return base.VisitUnary(node);
6546
}
66-
67-
protected override Expression VisitBinary(BinaryExpression node)
47+
48+
public IEnumerable<Expression> Find(Expression expression)
6849
{
69-
this.Visit(node.Left);
70-
this.Visit(node.Right);
71-
return node;
50+
FoundMembers.Clear();
51+
Visit(expression);
52+
53+
// Теперь фильтрация проще: благодаря правильному порядку обхода в VisitMember,
54+
// в список попадают только те члены, которые висят над параметром.
55+
return FoundMembers;
7256
}
57+
}
58+
7359

74-
protected override Expression VisitMethodCall(MethodCallExpression node)
60+
61+
public class GetParametr : ExpressionVisitor
62+
{
63+
private Expression parametr;
64+
65+
protected override Expression VisitParameter(ParameterExpression node)
7566
{
76-
if (node.Object != null)
77-
{
78-
this.Visit(node.Object);
79-
}
80-
foreach (var arg in node.Arguments)
81-
{
82-
this.Visit(arg);
83-
}
67+
68+
parametr = node;
69+
8470
return node;
8571
}
8672

87-
public IEnumerable<Expression> Find(Expression expression)
73+
public Expression GetParam(Expression expression)
8874
{
89-
FoundMembers.Clear();
9075
Visit(expression);
91-
return FoundMembers
92-
.Where(m =>
93-
{
94-
var current = m;
95-
96-
// Поднимаемся вверх по дереву выражения до самого корня этого MemberAccess
97-
while (current != null)
98-
{
99-
if (current is ParameterExpression p && _TargetParams.Contains(p))
100-
{
101-
return true; // Нашли целевой параметр в цепочке
102-
}
103-
104-
if (current is MemberExpression nextMember)
105-
{
106-
current = nextMember.Expression;
107-
}
108-
else if (current is UnaryExpression unary &&
109-
(unary.NodeType == ExpressionType.Convert || unary.NodeType == ExpressionType.ConvertChecked))
110-
{
111-
current = unary.Operand;
112-
}
113-
else
114-
{
115-
break;
116-
}
117-
}
118-
return false;
119-
});
120-
}
76+
77+
return parametr;
78+
}
12179
}

src/Mapster/Utils/ExpressionEx.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System;
33
using System.Collections;
44
using System.Collections.Generic;
5+
using System.Data.SqlTypes;
56
using System.Linq;
67
using System.Linq.Expressions;
78
using System.Reflection;
@@ -430,12 +431,13 @@ public static Expression ApplyPropertyNullPropagation(this Expression getter, Co
430431
var finder = new DirectParameterMemberFinder(source);
431432
var condition2 = finder.Find(getter)
432433
.Select(x => x.GetNullPropagationChecks(arg))
434+
.Where(x => x != null)
433435
.ToArray().ConcatPropagationChecks();
434436

435437
if (condition2 == null)
436438
return getter;
437439

438-
if (!getter.CanBeNull())
440+
if (!getter.Type.CanBeNull())
439441
{
440442
var transform = Expression.Convert(getter, typeof(Nullable<>).MakeGenericType(getter.Type));
441443
return Expression.Condition(condition2, transform, transform.Type.CreateDefault());

0 commit comments

Comments
 (0)