C# Driver ElemMatch bug(?) with DictionaryInterfaceImplementerSerializer

904 views
Skip to first unread message

Daniel Polistchuck

unread,
Jan 4, 2016, 5:00:18 PM1/4/16
to mongodb-user
Hi Folks,

I am receiving a System.InvalidOperationException when trying to use ElemMatch in a property that is mapped with the DictionaryInterfaceImplementerSerializer.

Here's an NUnit test that reproduces the issue:

using System;
using System.Collections.Generic;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Options;
using MongoDB.Bson.Serialization.Serializers;
using MongoDB.Driver;
using MongoDB.Driver.Builders;
using NUnit.Framework;

namespace CredMarket.Tests
{
    [TestFixture]
    public class ElemMatchTest
    {
        [Test]
        public void TestElemMatch()
        {
            BsonClassMap.RegisterClassMap<TestClass>(cm =>
            {
                cm.AutoMap();
                cm.MapMember(c => c.EnabledForProduct)
                    .SetSerializer(new DictionaryInterfaceImplementerSerializer<Dictionary<TestProduct, bool>>(
                        DictionaryRepresentation.ArrayOfDocuments, BsonSerializer.LookupSerializer<int>(),
                        BsonSerializer.LookupSerializer<bool>())
                    );
            });
            var client = new MongoClient("mongodb://localhost");
            var database = client.GetDatabase("test");
            var collection = database.GetCollection<TestClass>("testcollection");
            collection.DeleteMany(FilterDefinition<TestClass>.Empty);

            //Creating Document
            var doc = new TestClass
            {
                Id = Guid.NewGuid().ToString(),
                EnabledForProduct = new Dictionary<TestProduct, bool>
                {
                    {TestProduct.Product1, true}
                }
            };

            collection.InsertOne(doc);

            var foundDoc = collection.Find(d=>d.Id == doc.Id).Limit(1).FirstOrDefault();
            AssertDoc(foundDoc);

            var filter = Builders<TestClass>.Filter.ElemMatch(d => d.EnabledForProduct,
                k => k.Key == TestProduct.Product1 && k.Value);
            foundDoc = collection.Find(filter).Limit(1).FirstOrDefault();
            AssertDoc(foundDoc);
        }

        private static void AssertDoc(TestClass foundDoc)
        {
            Assert.IsNotNull(foundDoc);
            Assert.IsNotNull(foundDoc.EnabledForProduct);
            Assert.IsTrue(foundDoc.EnabledForProduct[TestProduct.Product1]);
        }
    }

    public class TestClass
    {
        public string Id { get; set; }
        public Dictionary<TestProduct,bool> EnabledForProduct { get; set; }
    }

    public enum TestProduct
    {
        Product1,Product2
    }
}

The "foundDoc = collection.Find(filter).Limit(1).FirstOrDefault()" call throws the following exception:

System.InvalidOperationException : The serializer for field 'EnabledForProduct' must implement IBsonArraySerializer and provide item serialization info.
   em MongoDB.Driver.ElementMatchFilterDefinition`2.Render(IBsonSerializer`1 documentSerializer, IBsonSerializerRegistry serializerRegistry)
   em MongoDB.Driver.MongoCollectionImpl`1.CreateFindOperation(FilterDefinition`1 filter, FindOptions`2 options)
   em MongoDB.Driver.MongoCollectionImpl`1.FindSync(FilterDefinition`1 filter, FindOptions`2 options, CancellationToken cancellationToken)
   em MongoDB.Driver.FindFluent`2.ToCursor(CancellationToken cancellationToken)
   em MongoDB.Driver.IAsyncCursorSourceExtensions.FirstOrDefault(IAsyncCursorSource`1 source, CancellationToken cancellationToken)
   em MongoDB.Driver.IFindFluentExtensions.FirstOrDefault(IFindFluent`2 find, CancellationToken cancellationToken)
   em CredMarket.Tests.ElemMatchTest.TestElemMatch() na ElemMatchTest.cs: line 49

Am I doing something wrong or there's actually a bug in the C# driver?

Craig Wilson

unread,
Jan 4, 2016, 6:32:00 PM1/4/16
to mongodb-user
Hi Daniel,

It looks like you've filed https://jira.mongodb.org/browse/CSHARP-1521. I believe you've found a bug. We'll track it in that ticket.

Craig
Reply all
Reply to author
Forward
0 new messages