@@ -89,8 +89,7 @@ public static AggregationExpression Translate(
89
89
foreach ( var binding in bindings )
90
90
{
91
91
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 ) ;
94
93
var valueExpression = memberAssignment . Expression ;
95
94
var valueTranslation = ExpressionToAggregationExpressionTranslator . Translate ( context , valueExpression ) ;
96
95
var memberSerializer = CoerceSourceSerializerToMemberSerializer ( memberMap , valueTranslation . Serializer ) ;
@@ -127,28 +126,26 @@ private static AggregationExpression TranslateWithTargetSerializer(
127
126
{
128
127
var constructorParameters = constructorInfo . GetParameters ( ) ;
129
128
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
131
130
var classMap = ( resultSerializer as IBsonClassMapSerializer ) ? . ClassMap ;
132
131
var creatorMap = classMap == null ? null : FindMatchingCreatorMap ( classMap , constructorInfo ) ;
133
132
if ( creatorMap == null && classMap != null )
134
133
{
135
- throw new ExpressionNotSupportedException ( expression , because : "couldn't find matching creator map" ) ;
134
+ throw new ExpressionNotSupportedException ( expression , because : "no matching creator map found " ) ;
136
135
}
137
136
var creatorMapArguments = creatorMap ? . Arguments ? . ToArray ( ) ;
138
137
139
138
for ( var i = 0 ; i < constructorParameters . Length ; i ++ )
140
139
{
141
- var parameterName = constructorParameters [ i ] . Name ;
142
140
var argumentExpression = constructorArguments [ i ] ;
143
- var memberName = creatorMapArguments ? [ i ] . Name ; // null if there is no classMap
144
141
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 ) ;
150
147
151
- var argumentTranslation = ExpressionToAggregationExpressionTranslator . Translate ( context , argumentExpression , memberSerializer ) ;
148
+ var argumentTranslation = ExpressionToAggregationExpressionTranslator . Translate ( context , argumentExpression , targetSerializer : memberSerializer ) ;
152
149
computedFields . Add ( AstExpression . ComputedField ( elementName , argumentTranslation . Ast ) ) ;
153
150
}
154
151
}
@@ -268,18 +265,18 @@ private static BsonCreatorMap FindMatchingCreatorMap(BsonClassMap classMap, Cons
268
265
private static ( string , IBsonSerializer ) FindMemberElementNameAndSerializer (
269
266
Expression expression ,
270
267
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 ,
272
276
IBsonDocumentSerializer documentSerializer ,
273
277
string constructorParameterName )
274
278
{
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
283
280
var bindingFlags = BindingFlags . Instance | BindingFlags . Public | BindingFlags . FlattenHierarchy | BindingFlags . IgnoreCase ;
284
281
foreach ( var memberInfo in documentSerializer . ValueType . GetMember ( constructorParameterName , bindingFlags ) )
285
282
{
@@ -289,25 +286,28 @@ private static (string, IBsonSerializer) FindMemberElementNameAndSerializer(
289
286
}
290
287
}
291
288
292
- return ( null , null ) ;
289
+ throw new ExpressionNotSupportedException ( expression , because : $ "no matching member map found for constructor parameter: { constructorParameterName } " ) ;
293
290
}
294
291
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 )
296
296
{
297
297
foreach ( var memberMap in classMap . DeclaredMemberMaps )
298
298
{
299
- if ( memberMap . MemberName == memberName )
299
+ if ( memberMap . MemberInfo == memberInfo )
300
300
{
301
301
return memberMap ;
302
302
}
303
303
}
304
304
305
305
if ( classMap . BaseClassMap != null )
306
306
{
307
- return FindMemberMap ( expression , classMap . BaseClassMap , memberName ) ;
307
+ return FindMemberMap ( expression , classMap . BaseClassMap , memberInfo ) ;
308
308
}
309
309
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 } ") ;
311
311
}
312
312
}
313
313
}
0 commit comments