Skip to content

Commit c620320

Browse files
committed
Refactor to make clearer that class map will be used if available.
1 parent a183bee commit c620320

File tree

1 file changed

+26
-26
lines changed

1 file changed

+26
-26
lines changed

src/MongoDB.Driver/Linq/Linq3Implementation/Translators/ExpressionToAggregationExpressionTranslators/MemberInitExpressionToAggregationExpressionTranslator.cs

+26-26
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,7 @@ public static AggregationExpression Translate(
8989
foreach (var binding in bindings)
9090
{
9191
var memberAssignment = (MemberAssignment)binding;
92-
var member = memberAssignment.Member;
93-
var memberMap = FindMemberMap(expression, classMap, member.Name);
92+
var memberMap = FindMemberMap(expression, classMap, memberInfo: memberAssignment.Member);
9493
var valueExpression = memberAssignment.Expression;
9594
var valueTranslation = ExpressionToAggregationExpressionTranslator.Translate(context, valueExpression);
9695
var memberSerializer = CoerceSourceSerializerToMemberSerializer(memberMap, valueTranslation.Serializer);
@@ -127,28 +126,26 @@ private static AggregationExpression TranslateWithTargetSerializer(
127126
{
128127
var constructorParameters = constructorInfo.GetParameters();
129128

130-
// if the documentSerializer is a BsonClassMappedSerializer we can use the classMap
129+
// if the documentSerializer is a BsonClassMappedSerializer we can use the classMap and creatorMap
131130
var classMap = (resultSerializer as IBsonClassMapSerializer)?.ClassMap;
132131
var creatorMap = classMap == null ? null : FindMatchingCreatorMap(classMap, constructorInfo);
133132
if (creatorMap == null && classMap != null)
134133
{
135-
throw new ExpressionNotSupportedException(expression, because: "couldn't find matching creator map");
134+
throw new ExpressionNotSupportedException(expression, because: "no matching creator map found");
136135
}
137136
var creatorMapArguments = creatorMap?.Arguments?.ToArray();
138137

139138
for (var i = 0; i < constructorParameters.Length; i++)
140139
{
141-
var parameterName = constructorParameters[i].Name;
142140
var argumentExpression = constructorArguments[i];
143-
var memberName = creatorMapArguments?[i].Name; // null if there is no classMap
144141

145-
var (elementName, memberSerializer) = FindMemberElementNameAndSerializer(argumentExpression, classMap, memberName, resultSerializer, parameterName);
146-
if (elementName == null)
147-
{
148-
throw new ExpressionNotSupportedException(expression, because: $"couldn't find matching class member for constructor parameter {parameterName}");
149-
}
142+
// if we have a classMap (and therefore a creatorMap also) use them
143+
// otherwise fall back to matching constructor parameter names to member names
144+
var (elementName, memberSerializer) = classMap != null ?
145+
FindMemberElementNameAndSerializer(argumentExpression, classMap, memberInfo: creatorMapArguments[i]) :
146+
FindMemberElementNameAndSerializer(argumentExpression, resultSerializer, constructorParameterName: constructorParameters[i].Name);
150147

151-
var argumentTranslation = ExpressionToAggregationExpressionTranslator.Translate(context, argumentExpression, memberSerializer);
148+
var argumentTranslation = ExpressionToAggregationExpressionTranslator.Translate(context, argumentExpression, targetSerializer: memberSerializer);
152149
computedFields.Add(AstExpression.ComputedField(elementName, argumentTranslation.Ast));
153150
}
154151
}
@@ -268,18 +265,18 @@ private static BsonCreatorMap FindMatchingCreatorMap(BsonClassMap classMap, Cons
268265
private static (string, IBsonSerializer) FindMemberElementNameAndSerializer(
269266
Expression expression,
270267
BsonClassMap classMap,
271-
string memberName,
268+
MemberInfo memberInfo)
269+
{
270+
var memberMap = FindMemberMap(expression, classMap, memberInfo);
271+
return (memberMap.ElementName, memberMap.GetSerializer());
272+
}
273+
274+
private static (string, IBsonSerializer) FindMemberElementNameAndSerializer(
275+
Expression expression,
272276
IBsonDocumentSerializer documentSerializer,
273277
string constructorParameterName)
274278
{
275-
// if we have a classMap use it
276-
if (classMap != null)
277-
{
278-
var memberMap = FindMemberMap(expression, classMap, memberName);
279-
return (memberMap.ElementName, memberMap.GetSerializer());
280-
}
281-
282-
// otherwise fall back to calling TryGetMemberSerializationInfo on potential matches
279+
// case insensitive GetMember could return some false hits but TryGetMemberSerializationInfo will filter them out
283280
var bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.IgnoreCase;
284281
foreach (var memberInfo in documentSerializer.ValueType.GetMember(constructorParameterName, bindingFlags))
285282
{
@@ -289,25 +286,28 @@ private static (string, IBsonSerializer) FindMemberElementNameAndSerializer(
289286
}
290287
}
291288

292-
return (null, null);
289+
throw new ExpressionNotSupportedException(expression, because: $"no matching member map found for constructor parameter: {constructorParameterName}");
293290
}
294291

295-
private static BsonMemberMap FindMemberMap(Expression expression, BsonClassMap classMap, string memberName)
292+
private static BsonMemberMap FindMemberMap(
293+
Expression expression,
294+
BsonClassMap classMap,
295+
MemberInfo memberInfo)
296296
{
297297
foreach (var memberMap in classMap.DeclaredMemberMaps)
298298
{
299-
if (memberMap.MemberName == memberName)
299+
if (memberMap.MemberInfo == memberInfo)
300300
{
301301
return memberMap;
302302
}
303303
}
304304

305305
if (classMap.BaseClassMap != null)
306306
{
307-
return FindMemberMap(expression, classMap.BaseClassMap, memberName);
307+
return FindMemberMap(expression, classMap.BaseClassMap, memberInfo);
308308
}
309309

310-
throw new ExpressionNotSupportedException(expression, because: $"can't find member map: {memberName}");
310+
throw new ExpressionNotSupportedException(expression, because: $"no member map found for member: {memberInfo.Name}");
311311
}
312312
}
313313
}

0 commit comments

Comments
 (0)