Skip to content

Commit af265ba

Browse files
committed
fixed projection problems with inheritance
1 parent 98e7d4b commit af265ba

File tree

4 files changed

+78
-27
lines changed

4 files changed

+78
-27
lines changed

source/MongoDB/Cursor_1.cs

+57-5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
using MongoDB.Protocol;
66
using MongoDB.Serialization;
77
using System.Linq;
8+
using MongoDB.Util;
9+
using MongoDB.Configuration.Mapping.Model;
10+
using MongoDB.Configuration.Mapping;
811

912
namespace MongoDB
1013
{
@@ -25,6 +28,7 @@ public class Cursor<T> : ICursor<T> where T : class
2528
private int _skip;
2629
private bool _keepCursor;
2730
private readonly ISerializationFactory _serializationFactory;
31+
private readonly IMappingStore _mappingStore;
2832

2933
/// <summary>
3034
/// Initializes a new instance of the <see cref="Cursor&lt;T&gt;"/> class.
@@ -33,14 +37,15 @@ public class Cursor<T> : ICursor<T> where T : class
3337
/// <param name="connection">The conn.</param>
3438
/// <param name="databaseName">Name of the database.</param>
3539
/// <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)
3741
{
3842
//Todo: add public constrcutor for users to call
3943
IsModifiable = true;
4044
_connection = connection;
4145
_databaseName = databaseName;
4246
FullCollectionName = databaseName + "." + collectionName;
4347
_serializationFactory = serializationFactory;
48+
_mappingStore = mappingStore;
4449
}
4550

4651
/// <summary>
@@ -54,8 +59,8 @@ internal Cursor(ISerializationFactory serializationFactory, Connection connectio
5459
/// <param name="limit">The limit.</param>
5560
/// <param name="skip">The skip.</param>
5661
/// <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)
5964
{
6065
//Todo: add public constrcutor for users to call
6166
if (spec == null)
@@ -333,7 +338,7 @@ private ReplyMessage<TReply> RetrieveData<TReply>() where TReply : class
333338
NumberToReturn = _limit,
334339
NumberToSkip = _skip,
335340
Options = _options,
336-
ReturnFieldSelector = _fields
341+
ReturnFieldSelector = ConvertFieldSelectorToDocument(_fields)
337342
};
338343
}
339344
else
@@ -391,5 +396,52 @@ private object BuildSpec(){
391396
document["$query"] = _spec;
392397
return document;
393398
}
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+
}
394446
}
395-
}
447+
}

source/MongoDB/MongoCollection_1.cs

+1-21
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ public ICursor<T> Find(object spec, int limit, int skip){
159159
public ICursor<T> Find(object spec, int limit, int skip, object fields){
160160
if (spec == null)
161161
spec = new Document();
162-
return new Cursor<T>(_configuration.SerializationFactory, _connection, DatabaseName, Name, spec, limit, skip, fields);
162+
return new Cursor<T>(_configuration.SerializationFactory, _configuration.MappingStore, _connection, DatabaseName, Name, spec, limit, skip, fields);
163163
}
164164

165165
/// <summary>
@@ -603,25 +603,5 @@ private object EnsureUpdateDocument(object document)
603603

604604
return document;
605605
}
606-
607-
private Document ConvertObjectToDocument(object document)
608-
{
609-
Document doc = document as Document;
610-
if (doc != null)
611-
return doc;
612-
613-
if (document is T)
614-
{
615-
var classMap = _configuration.MappingStore.GetClassMap(typeof(T));
616-
foreach (PersistentMemberMap memberMap in classMap)
617-
{
618-
doc[memberMap.MemberName] = memberMap.GetValue(document);
619-
}
620-
}
621-
else //anonymous type...
622-
{
623-
624-
}
625-
}
626606
}
627607
}

source/MongoDB/Protocol/QueryMessage.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ namespace MongoDB.Protocol
1717
/// [ BSON returnFieldSelector; ] // OPTIONAL : selector indicating the fields to return. See below for details.
1818
/// }
1919
/// </remarks>
20-
internal class QueryMessage<T> : RequestMessageBase
20+
internal class QueryMessage : RequestMessageBase
2121
{
2222
/// <summary>
2323
/// Initializes a new instance of the <see cref="QueryMessage"/> class.

source/MongoDB/Util/TypeHelper.cs

+19
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,24 @@ internal static Type GetNonNullableType(Type type)
5454
{
5555
return IsNullableType(type) ? type.GetGenericArguments()[0] : type;
5656
}
57+
58+
internal static bool IsNativeToMongo(Type type)
59+
{
60+
var typeCode = Type.GetTypeCode(type);
61+
62+
if (typeCode != TypeCode.Object)
63+
return true;
64+
65+
if (type == typeof(Guid))
66+
return true;
67+
68+
if (type == typeof(Oid))
69+
return true;
70+
71+
if (type == typeof(byte[]))
72+
return true;
73+
74+
return false;
75+
}
5776
}
5877
}

0 commit comments

Comments
 (0)