Skip to content

Commit 8f570e6

Browse files
committed
CSHARP-1521: added support for querying dictionaries serialized as array of documents.
1 parent 399959d commit 8f570e6

File tree

3 files changed

+71
-1
lines changed

3 files changed

+71
-1
lines changed

src/MongoDB.Bson/Serialization/Serializers/DictionarySerializerBase.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,7 @@ private string SerializeKeyString(object key)
338338
/// <typeparam name="TValue">The type of the values.</typeparam>
339339
public abstract class DictionarySerializerBase<TDictionary, TKey, TValue> :
340340
ClassSerializerBase<TDictionary>,
341+
IBsonArraySerializer,
341342
IBsonDocumentSerializer,
342343
IBsonDictionarySerializer
343344
where TDictionary : class, IDictionary<TKey, TValue>
@@ -463,6 +464,26 @@ public IBsonSerializer<TValue> ValueSerializer
463464
}
464465

465466
// public methods
467+
/// <inheritdoc/>
468+
public bool TryGetItemSerializationInfo(out BsonSerializationInfo serializationInfo)
469+
{
470+
if (_dictionaryRepresentation != DictionaryRepresentation.ArrayOfDocuments)
471+
{
472+
serializationInfo = null;
473+
return false;
474+
}
475+
476+
var serializer = new KeyValuePairSerializer<TKey, TValue>(
477+
BsonType.Document,
478+
_lazyKeySerializer.Value,
479+
_lazyValueSerializer.Value);
480+
serializationInfo = new BsonSerializationInfo(
481+
null,
482+
serializer,
483+
serializer.ValueType);
484+
return true;
485+
}
486+
466487
/// <inheritdoc/>
467488
public bool TryGetMemberSerializationInfo(string memberName, out BsonSerializationInfo serializationInfo)
468489
{

src/MongoDB.Bson/Serialization/Serializers/KeyValuePairSerializer.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ namespace MongoDB.Bson.Serialization.Serializers
2727
/// </summary>
2828
/// <typeparam name="TKey">The type of the keys.</typeparam>
2929
/// <typeparam name="TValue">The type of the values.</typeparam>
30-
public class KeyValuePairSerializer<TKey, TValue> : StructSerializerBase<KeyValuePair<TKey, TValue>>
30+
public class KeyValuePairSerializer<TKey, TValue> :
31+
StructSerializerBase<KeyValuePair<TKey, TValue>>,
32+
IBsonDocumentSerializer
3133
{
3234
// private constants
3335
private static class Flags
@@ -206,6 +208,29 @@ public override void Serialize(BsonSerializationContext context, BsonSerializati
206208
}
207209
}
208210

211+
/// <inheritdoc />
212+
public bool TryGetMemberSerializationInfo(string memberName, out BsonSerializationInfo serializationInfo)
213+
{
214+
if (_representation != BsonType.Document)
215+
{
216+
serializationInfo = null;
217+
return false;
218+
}
219+
220+
switch (memberName)
221+
{
222+
case "Key":
223+
serializationInfo = new BsonSerializationInfo("k", _lazyKeySerializer.Value, _lazyKeySerializer.Value.ValueType);
224+
return true;
225+
case "Value":
226+
serializationInfo = new BsonSerializationInfo("v", _lazyValueSerializer.Value, _lazyValueSerializer.Value.ValueType);
227+
return true;
228+
}
229+
230+
serializationInfo = null;
231+
return false;
232+
}
233+
209234
// private methods
210235
private KeyValuePair<TKey, TValue> DeserializeArrayRepresentation(BsonDeserializationContext context)
211236
{

src/MongoDB.Driver.Tests/FilterDefinitionBuilderTests.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
*/
1515

1616
using System;
17+
using System.Collections.Generic;
1718
using System.Linq.Expressions;
1819
using FluentAssertions;
1920
using MongoDB.Bson;
@@ -209,6 +210,15 @@ public void ElemMatch_Typed()
209210
Assert(subject.ElemMatch(x => x.Pets, x => x.Name == "Fluffy"), "{pets: {$elemMatch: {name: 'Fluffy'}}}");
210211
}
211212

213+
[Test]
214+
public void ElemMatch_over_dictionary_represented_as_array_of_documents()
215+
{
216+
var subject = CreateSubject<Feature>();
217+
var filter = subject.ElemMatch(x => x.Enabled, x => x.Key == ProductType.Auto && x.Value);
218+
219+
Assert(filter, "{Enabled: {$elemMatch: { k: 0, v: true}}}");
220+
}
221+
212222
[Test]
213223
public void Empty()
214224
{
@@ -992,5 +1002,19 @@ private class Dog : Mammal
9921002
[BsonElement("isLapDog")]
9931003
public bool IsLapDog { get; set; }
9941004
}
1005+
1006+
private class Feature
1007+
{
1008+
public ObjectId Id { get; set; }
1009+
1010+
[BsonDictionaryOptions(Representation = Bson.Serialization.Options.DictionaryRepresentation.ArrayOfDocuments)]
1011+
public Dictionary<ProductType, bool> Enabled { get; set; }
1012+
}
1013+
1014+
private enum ProductType
1015+
{
1016+
Auto,
1017+
Home
1018+
}
9951019
}
9961020
}

0 commit comments

Comments
 (0)