[CSHARP-2991] Regression of CSHARP-1521. ElemMatch requires IBsonArraySerializer for DictionaryInterfaceImplementerSerializer Created: 03/Mar/20  Updated: 27/Oct/23  Resolved: 12/Mar/20

Status: Closed
Project: C# Driver
Component/s: BSON, Operations
Affects Version/s: 2.10.2
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Damian Miłosz Assignee: Dmitry Lukyanov (Inactive)
Resolution: Works as Designed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
related to CSHARP-3010 Add a clear error when a serializer f... Backlog
is related to CSHARP-1521 ElemMatch requires IBsonArraySerializ... Closed

 Description   

The issue CSHARP-1521 occurs again in the newest 2.10.2 C# Driver.  Error message: 

The serializer for field 'MyDictionary' must implement IBsonArraySerializer and provide item serialization info.

 

Model is definied like this:

 public class Model
 {
     public Dictionary<long, Guid> MyDictionary { get; set; }
 }

 

ClassMap is registered as below:

 BsonClassMap.RegisterClassMap<Model>(cm =>
 {
     cm.AutoMap();
     cm.MapProperty(c => c.MyDictionary).SetSerializer(new DictionaryInterfaceImplementerSerializer<Dictionary<long, Guid>>(DictionaryRepresentation.ArrayOfDocuments));
 });

 

 

My query:

Builders<Model>.Filter.ElemMatch(request => request.MyDictionary, f => f.Value.Equals(value));

 

And I have a workaround that works for me, but I don't want to use it in long term:

public class DictionaryArrayInterfaceImplementerSerializer<TDictionary, TKey, TValue> : DictionaryInterfaceImplementerSerializer<TDictionary>, IBsonArraySerializer where TDictionary : class, IDictionary, new()
{
    public DictionaryArrayInterfaceImplementerSerializer(DictionaryRepresentation dictionaryRepresentation) : base(dictionaryRepresentation)
    { }    public bool TryGetItemSerializationInfo(out BsonSerializationInfo serializationInfo)
    {
        var serializer = new KeyValuePairSerializer<TKey, TValue>();
        serializationInfo = new BsonSerializationInfo(
            null,
            serializer,
            serializer.ValueType);        return true;
    }
}

Basically I can create new serializer, which inherits from DictionaryInterfaceImplementerSerializer, but also implements IBsonArraySerializer and then everything works.

 

 



 Comments   
Comment by Damian Miłosz [ 13/Mar/20 ]

It's working, thanks! I think it's worth fixing the section in the documentation: https://mongodb.github.io/mongo-csharp-driver/2.10/reference/bson/mapping/#dictionary-serialization-options to make it clear

Comment by Dmitry Lukyanov (Inactive) [ 12/Mar/20 ]

Hello sekalek5@gmail.com,
please use DictionaryInterfaceImplementerSerializer<TDictionary, TKey, TValue> instead of DictionaryInterfaceImplementerSerializer<TDictionary>:

            var value = new KeyValuePair<long, Guid>(1, Guid.NewGuid());
            BsonClassMap.RegisterClassMap<Model>(cm =>
            {
                cm.AutoMap();
                cm
                .MapProperty(c => c.MyDictionary)
                .SetSerializer(
                    new DictionaryInterfaceImplementerSerializer<Dictionary<long, Guid>, long, Guid>(
                        DictionaryRepresentation.ArrayOfDocuments));
            });
 
            var serializer = BsonSerializer.SerializerRegistry.GetSerializer<Model>();
            var test = Builders<Model>.Filter.ElemMatch(request => request.MyDictionary, f => f.Value.Equals(value));
            var res = test.Render(serializer, BsonSerializer.SerializerRegistry);

This behavior is related to the fact that DictionaryInterfaceImplementerSerializer<TDictionary> is designed to work with not generic types, like Hashtable

Generated at Wed Feb 07 21:44:03 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.