15
15
16
16
using System ;
17
17
using FluentAssertions ;
18
+ using MongoDB . Bson . Serialization . Attributes ;
18
19
using MongoDB . Driver . Linq ;
19
20
using Xunit ;
20
21
21
22
namespace MongoDB . Driver . Tests . Linq . Linq3ImplementationTests . Translators . ExpressionToAggregationExpressionTranslators
22
23
{
23
24
public class MemberInitExpressionToAggregationExpressionTranslatorTests : Linq3IntegrationTest
24
25
{
25
- private readonly IMongoCollection < MyData > _collection ;
26
-
27
- public MemberInitExpressionToAggregationExpressionTranslatorTests ( )
26
+ [ Fact ]
27
+ public void Should_project_class_via_parameterless_constructor ( )
28
28
{
29
- _collection = CreateCollection ( LinqProvider . V3 ) ;
29
+ var collection = CreateCollection ( ) ;
30
+
31
+ var queryable = collection . AsQueryable ( )
32
+ . Select ( x => new SpawnDataClassParameterless
33
+ {
34
+ Identifier = x . Id ,
35
+ SpawnDate = x . Date ,
36
+ SpawnText = x . Text
37
+ } ) ;
38
+
39
+ var stages = Translate ( collection , queryable ) ;
40
+ AssertStages ( stages , "{ $project : { Identifier : '$_id', SpawnDate : '$Date', SpawnText : '$Text', _id : 0 } }" ) ;
41
+
42
+ var results = queryable . Single ( ) ;
43
+
44
+ results . SpawnDate . Should ( ) . Be ( new DateTime ( 2023 , 1 , 2 , 3 , 4 , 5 , DateTimeKind . Utc ) ) ;
45
+ results . SpawnText . Should ( ) . Be ( "data text" ) ;
46
+ results . Identifier . Should ( ) . Be ( 1 ) ;
30
47
}
31
48
32
49
[ Fact ]
33
- public void Should_project_via_parameterless_constructor ( )
50
+ public void Should_project_struct_via_parameterless_constructor ( )
34
51
{
35
- var queryable = _collection . AsQueryable ( )
36
- . Select ( x => new SpawnDataParameterless
52
+ var collection = CreateCollection ( ) ;
53
+
54
+ var queryable = collection . AsQueryable ( )
55
+ . Select ( x => new SpawnDataStructParameterless
37
56
{
38
57
Identifier = x . Id ,
39
58
SpawnDate = x . Date ,
40
59
SpawnText = x . Text
41
60
} ) ;
42
61
43
- var stages = Translate ( _collection , queryable ) ;
62
+ var stages = Translate ( collection , queryable ) ;
44
63
AssertStages ( stages , "{ $project : { Identifier : '$_id', SpawnDate : '$Date', SpawnText : '$Text', _id : 0 } }" ) ;
45
64
46
65
var results = queryable . Single ( ) ;
@@ -51,15 +70,38 @@ public void Should_project_via_parameterless_constructor()
51
70
}
52
71
53
72
[ Fact ]
54
- public void Should_project_via_constructor ( )
73
+ public void Should_project_class_via_constructor ( )
55
74
{
56
- var queryable = _collection . AsQueryable ( )
57
- . Select ( x => new SpawnData ( x . Id , x . Date )
75
+ var collection = CreateCollection ( ) ;
76
+
77
+ var queryable = collection . AsQueryable ( )
78
+ . Select ( x => new SpawnDataClass ( x . Id , x . Date )
79
+ {
80
+ SpawnText = x . Text
81
+ } ) ;
82
+
83
+ var stages = Translate ( collection , queryable ) ;
84
+ AssertStages ( stages , "{ $project : { Identifier : '$_id', SpawnDate : '$Date', SpawnText : '$Text', _id : 0 } }" ) ;
85
+
86
+ var results = queryable . Single ( ) ;
87
+
88
+ results . SpawnDate . Should ( ) . Be ( new DateTime ( 2023 , 1 , 2 , 3 , 4 , 5 , DateTimeKind . Utc ) ) ;
89
+ results . SpawnText . Should ( ) . Be ( "data text" ) ;
90
+ results . Identifier . Should ( ) . Be ( 1 ) ;
91
+ }
92
+
93
+ [ Fact ]
94
+ public void Should_project_struct_via_constructor ( )
95
+ {
96
+ var collection = CreateCollection ( ) ;
97
+
98
+ var queryable = collection . AsQueryable ( )
99
+ . Select ( x => new SpawnDataStruct ( x . Id , x . Date )
58
100
{
59
101
SpawnText = x . Text
60
102
} ) ;
61
103
62
- var stages = Translate ( _collection , queryable ) ;
104
+ var stages = Translate ( collection , queryable ) ;
63
105
AssertStages ( stages , "{ $project : { Identifier : '$_id', SpawnDate : '$Date', SpawnText : '$Text', _id : 0 } }" ) ;
64
106
65
107
var results = queryable . Single ( ) ;
@@ -72,13 +114,15 @@ public void Should_project_via_constructor()
72
114
[ Fact ]
73
115
public void Should_project_via_constructor_with_inheritance ( )
74
116
{
75
- var queryable = _collection . AsQueryable ( )
117
+ var collection = CreateCollection ( ) ;
118
+
119
+ var queryable = collection . AsQueryable ( )
76
120
. Select ( x => new InheritedSpawnData ( x . Id , x . Date )
77
121
{
78
122
SpawnText = x . Text
79
123
} ) ;
80
124
81
- var stages = Translate ( _collection , queryable ) ;
125
+ var stages = Translate ( collection , queryable ) ;
82
126
AssertStages ( stages , "{ $project : { Identifier : '$_id', SpawnDate : '$Date', SpawnText : '$Text', _id : 0 } }" ) ;
83
127
84
128
var results = queryable . Single ( ) ;
@@ -88,9 +132,9 @@ public void Should_project_via_constructor_with_inheritance()
88
132
results . Identifier . Should ( ) . Be ( 1 ) ;
89
133
}
90
134
91
- private IMongoCollection < MyData > CreateCollection ( LinqProvider linqProvider )
135
+ private IMongoCollection < MyData > CreateCollection ( )
92
136
{
93
- var collection = GetCollection < MyData > ( "data" , linqProvider ) ;
137
+ var collection = GetCollection < MyData > ( "data" ) ;
94
138
95
139
CreateCollection (
96
140
collection ,
@@ -106,23 +150,70 @@ public class MyData
106
150
public string Text ;
107
151
}
108
152
109
- public class SpawnDataParameterless
153
+ public class SpawnDataClassParameterless
110
154
{
111
155
public int Identifier ;
112
156
public DateTime SpawnDate ;
113
157
public string SpawnText ;
114
158
}
115
159
116
- public class SpawnData
160
+ public struct SpawnDataStructParameterless
161
+ {
162
+ public int Identifier ;
163
+ public DateTime SpawnDate ;
164
+ public string SpawnText ;
165
+
166
+ // this constructor is required to be able to deserialize instances of this struct
167
+ [ BsonConstructor ]
168
+ public SpawnDataStructParameterless ( int identifier , DateTime spawnDate , string spawnText )
169
+ {
170
+ Identifier = identifier ;
171
+ SpawnDate = spawnDate ;
172
+ SpawnText = spawnText ;
173
+ }
174
+ }
175
+
176
+ public class SpawnDataClass
177
+ {
178
+ public readonly int Identifier ;
179
+ public DateTime SpawnDate ;
180
+ private string spawnText ;
181
+
182
+ public SpawnDataClass ( int identifier , DateTime spawnDate )
183
+ {
184
+ Identifier = identifier ;
185
+ SpawnDate = spawnDate ;
186
+ }
187
+
188
+ public string SpawnText
189
+ {
190
+ get => spawnText ;
191
+ set => spawnText = value ;
192
+ }
193
+ }
194
+
195
+ public struct SpawnDataStruct
117
196
{
197
+ [ BsonElement ]
118
198
public readonly int Identifier ;
119
199
public DateTime SpawnDate ;
120
200
private string spawnText ;
121
201
122
- public SpawnData ( int identifier , DateTime spawnDate )
202
+ // this constructor is required for the test to compile
203
+ public SpawnDataStruct ( int identifier , DateTime spawnDate )
204
+ {
205
+ Identifier = identifier ;
206
+ SpawnDate = spawnDate ;
207
+ spawnText = default ;
208
+ }
209
+
210
+ // this constructor is required to be able to deserialize instances of this struct
211
+ [ BsonConstructor ]
212
+ public SpawnDataStruct ( int identifier , DateTime spawnDate , string spawnText )
123
213
{
124
214
Identifier = identifier ;
125
215
SpawnDate = spawnDate ;
216
+ this . spawnText = spawnText ;
126
217
}
127
218
128
219
public string SpawnText
@@ -132,7 +223,7 @@ public string SpawnText
132
223
}
133
224
}
134
225
135
- public class InheritedSpawnData : SpawnData
226
+ public class InheritedSpawnData : SpawnDataClass
136
227
{
137
228
public InheritedSpawnData ( int identifier , DateTime spawnDate )
138
229
: base ( identifier , spawnDate )
0 commit comments