15
15
16
16
using System ;
17
17
using System . Collections . Generic ;
18
- using System . Collections . ObjectModel ;
19
- using System . Linq ;
20
18
using System . Linq . Expressions ;
21
- using System . Reflection ;
22
- using MongoDB . Bson . Serialization ;
23
- using MongoDB . Driver . Linq . Linq3Implementation . Ast ;
24
- using MongoDB . Driver . Linq . Linq3Implementation . Ast . Expressions ;
25
19
26
20
namespace MongoDB . Driver . Linq . Linq3Implementation . Translators . ExpressionToAggregationExpressionTranslators
27
21
{
@@ -30,9 +24,6 @@ internal static class NewExpressionToAggregationExpressionTranslator
30
24
public static AggregationExpression Translate ( TranslationContext context , NewExpression expression )
31
25
{
32
26
var expressionType = expression . Type ;
33
- var constructorInfo = expression . Constructor ;
34
- var arguments = expression . Arguments . ToArray ( ) ;
35
- var members = expression . Members ;
36
27
37
28
if ( expressionType == typeof ( DateTime ) )
38
29
{
@@ -50,91 +41,7 @@ public static AggregationExpression Translate(TranslationContext context, NewExp
50
41
{
51
42
return NewTupleExpressionToAggregationExpressionTranslator . Translate ( context , expression ) ;
52
43
}
53
-
54
- var classMapType = typeof ( BsonClassMap < > ) . MakeGenericType ( expressionType ) ;
55
- var classMap = ( BsonClassMap ) Activator . CreateInstance ( classMapType ) ;
56
- var computedFields = new List < AstComputedField > ( ) ;
57
-
58
- // if Members is not null then trust Members more than the constructor parameter names (which are compiler generated for anonymous types)
59
- if ( members == null )
60
- {
61
- var membersList = constructorInfo . GetParameters ( ) . Select ( p => GetMatchingMember ( expression , p . Name ) ) . ToList ( ) ;
62
- members = new ReadOnlyCollection < MemberInfo > ( membersList ) ;
63
- }
64
-
65
- for ( var i = 0 ; i < arguments . Length ; i ++ )
66
- {
67
- var valueExpression = arguments [ i ] ;
68
- var valueTranslation = ExpressionToAggregationExpressionTranslator . Translate ( context , valueExpression ) ;
69
- var valueType = valueExpression . Type ;
70
- var valueSerializer = valueTranslation . Serializer ?? BsonSerializer . LookupSerializer ( valueType ) ;
71
- var defaultValue = GetDefaultValue ( valueType ) ;
72
- var memberMap = classMap . MapMember ( members [ i ] ) . SetSerializer ( valueSerializer ) . SetDefaultValue ( defaultValue ) ;
73
- computedFields . Add ( AstExpression . ComputedField ( memberMap . ElementName , valueTranslation . Ast ) ) ;
74
- }
75
-
76
- // map any public fields or properties that didn't match a constructor argument
77
- foreach ( var member in expressionType . GetFields ( ) . Cast < MemberInfo > ( ) . Concat ( expressionType . GetProperties ( ) ) )
78
- {
79
- if ( ! members . Contains ( member ) )
80
- {
81
- var valueType = member switch
82
- {
83
- FieldInfo fieldInfo => fieldInfo . FieldType ,
84
- PropertyInfo propertyInfo => propertyInfo . PropertyType ,
85
- _ => throw new Exception ( $ "Unexpected member type: { member . MemberType } ")
86
- } ;
87
- var valueSerializer = context . KnownSerializersRegistry . GetSerializer ( expression , valueType ) ;
88
- var defaultValue = GetDefaultValue ( valueType ) ;
89
- classMap . MapMember ( member ) . SetSerializer ( valueSerializer ) . SetDefaultValue ( defaultValue ) ;
90
- }
91
- }
92
-
93
- classMap . MapConstructor ( constructorInfo , members . Select ( m => m . Name ) . ToArray ( ) ) ;
94
- classMap . Freeze ( ) ;
95
-
96
- var ast = AstExpression . ComputedDocument ( computedFields ) ;
97
- var serializerType = typeof ( BsonClassMapSerializer < > ) . MakeGenericType ( expression . Type ) ;
98
- // Note that we should use context.KnownSerializersRegistry to find the serializer,
99
- // but the above implementation builds up computedFields during the mapping process.
100
- // We need to figure out how to resolve the serializer from KnownSerializers and then
101
- // populate computedFields from that resolved serializer.
102
- var serializer = ( IBsonSerializer ) Activator . CreateInstance ( serializerType , classMap ) ;
103
-
104
- return new AggregationExpression ( expression , ast , serializer ) ;
105
- }
106
-
107
- private static object GetDefaultValue ( Type type )
108
- {
109
- if ( type . IsValueType )
110
- {
111
- return Activator . CreateInstance ( type ) ;
112
- }
113
- else
114
- {
115
- return null ;
116
- }
117
- }
118
-
119
- private static MemberInfo GetMatchingMember ( NewExpression expression , string constructorParameterName )
120
- {
121
- foreach ( var field in expression . Type . GetFields ( ) )
122
- {
123
- if ( field . Name . Equals ( constructorParameterName , StringComparison . OrdinalIgnoreCase ) )
124
- {
125
- return field ;
126
- }
127
- }
128
-
129
- foreach ( var property in expression . Type . GetProperties ( ) )
130
- {
131
- if ( property . Name . Equals ( constructorParameterName , StringComparison . OrdinalIgnoreCase ) )
132
- {
133
- return property ;
134
- }
135
- }
136
-
137
- throw new ExpressionNotSupportedException ( expression , because : $ "constructor parameter { constructorParameterName } does not match any public field or property") ;
44
+ return MemberInitExpressionToAggregationExpressionTranslator . Translate ( context , expression , expression , Array . Empty < MemberBinding > ( ) ) ;
138
45
}
139
46
}
140
47
}
0 commit comments