5
5
using MongoDB . Protocol ;
6
6
using MongoDB . Serialization ;
7
7
using System . Linq ;
8
+ using MongoDB . Util ;
9
+ using MongoDB . Configuration . Mapping . Model ;
10
+ using MongoDB . Configuration . Mapping ;
8
11
9
12
namespace MongoDB
10
13
{
@@ -25,6 +28,7 @@ public class Cursor<T> : ICursor<T> where T : class
25
28
private int _skip ;
26
29
private bool _keepCursor ;
27
30
private readonly ISerializationFactory _serializationFactory ;
31
+ private readonly IMappingStore _mappingStore ;
28
32
29
33
/// <summary>
30
34
/// Initializes a new instance of the <see cref="Cursor<T>"/> class.
@@ -33,14 +37,15 @@ public class Cursor<T> : ICursor<T> where T : class
33
37
/// <param name="connection">The conn.</param>
34
38
/// <param name="databaseName">Name of the database.</param>
35
39
/// <param name="collectionName">Name of the collection.</param>
36
- internal Cursor ( ISerializationFactory serializationFactory , Connection connection , string databaseName , string collectionName )
40
+ internal Cursor ( ISerializationFactory serializationFactory , IMappingStore mappingStore , Connection connection , string databaseName , string collectionName )
37
41
{
38
42
//Todo: add public constrcutor for users to call
39
43
IsModifiable = true ;
40
44
_connection = connection ;
41
45
_databaseName = databaseName ;
42
46
FullCollectionName = databaseName + "." + collectionName ;
43
47
_serializationFactory = serializationFactory ;
48
+ _mappingStore = mappingStore ;
44
49
}
45
50
46
51
/// <summary>
@@ -54,8 +59,8 @@ internal Cursor(ISerializationFactory serializationFactory, Connection connectio
54
59
/// <param name="limit">The limit.</param>
55
60
/// <param name="skip">The skip.</param>
56
61
/// <param name="fields">The fields.</param>
57
- internal Cursor ( ISerializationFactory serializationFactory , Connection connection , string databaseName , string collectionName , object spec , int limit , int skip , object fields )
58
- : this ( serializationFactory , connection , databaseName , collectionName )
62
+ internal Cursor ( ISerializationFactory serializationFactory , IMappingStore mappingStore , Connection connection , string databaseName , string collectionName , object spec , int limit , int skip , object fields )
63
+ : this ( serializationFactory , mappingStore , connection , databaseName , collectionName )
59
64
{
60
65
//Todo: add public constrcutor for users to call
61
66
if ( spec == null )
@@ -333,7 +338,7 @@ private ReplyMessage<TReply> RetrieveData<TReply>() where TReply : class
333
338
NumberToReturn = _limit ,
334
339
NumberToSkip = _skip ,
335
340
Options = _options ,
336
- ReturnFieldSelector = _fields
341
+ ReturnFieldSelector = ConvertFieldSelectorToDocument ( _fields )
337
342
} ;
338
343
}
339
344
else
@@ -391,5 +396,52 @@ private object BuildSpec(){
391
396
document [ "$query" ] = _spec ;
392
397
return document ;
393
398
}
399
+
400
+ private Document ConvertFieldSelectorToDocument ( object document )
401
+ {
402
+ Document doc ;
403
+ if ( document == null )
404
+ doc = new Document ( ) ;
405
+ else
406
+ doc = ConvertExampleToDocument ( document ) as Document ;
407
+
408
+ if ( doc == null )
409
+ throw new NotSupportedException ( "An entity type is not supported in field selection. Use either a document or an anonymous type." ) ;
410
+
411
+ var classMap = _mappingStore . GetClassMap ( typeof ( T ) ) ;
412
+ if ( doc . Count > 0 && ( classMap . IsPolymorphic || classMap . IsSubClass ) )
413
+ doc [ classMap . DiscriminatorAlias ] = true ;
414
+
415
+ return doc . Count == 0 ? null : doc ;
416
+ }
417
+
418
+ private object ConvertExampleToDocument ( object document )
419
+ {
420
+ if ( document == null )
421
+ return null ;
422
+
423
+ Document doc = document as Document ;
424
+ if ( doc != null )
425
+ return doc ;
426
+
427
+ doc = new Document ( ) ;
428
+
429
+ if ( ! ( document is T ) ) //some type that is being used as an example
430
+ {
431
+ foreach ( var prop in document . GetType ( ) . GetProperties ( ) )
432
+ {
433
+ if ( ! prop . CanRead )
434
+ continue ;
435
+
436
+ object value = prop . GetValue ( document , null ) ;
437
+ if ( ! TypeHelper . IsNativeToMongo ( prop . PropertyType ) )
438
+ value = ConvertExampleToDocument ( value ) ;
439
+
440
+ doc [ prop . Name ] = value ;
441
+ }
442
+ }
443
+
444
+ return doc ;
445
+ }
394
446
}
395
- }
447
+ }
0 commit comments