-
Type: Bug
-
Resolution: Done
-
Priority: Major - P3
-
Affects Version/s: 2.4.1
-
Component/s: API, Serialization
-
None
I got an exception when I had updated MongoDB.Driver from 2.4.0 to 2.4.1.
System.NotSupportedException : Values of type 'String' cannot be deserialized using a serializer of type 'CastingSerializer<String, IEnumerable<String>>'. в MongoDB.Bson.Serialization.Serializers.SerializerBase`1.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) в MongoDB.Bson.Serialization.IBsonSerializerExtensions.Deserialize[TValue](IBsonSerializer`1 serializer, BsonDeserializationContext context) в MongoDB.Bson.Serialization.Serializers.EnumerableSerializerBase`2.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) в MongoDB.Bson.Serialization.IBsonSerializerExtensions.Deserialize[TValue](IBsonSerializer`1 serializer, BsonDeserializationContext context) в MongoDB.Driver.Core.Operations.ElementDeserializer`1.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) в MongoDB.Bson.Serialization.IBsonSerializerExtensions.Deserialize[TValue](IBsonSerializer`1 serializer, BsonDeserializationContext context) в MongoDB.Driver.Core.WireProtocol.CommandWireProtocol`1.ProcessReply(ConnectionId connectionId, ReplyMessage`1 reply) в MongoDB.Driver.Core.WireProtocol.CommandWireProtocol`1.Execute(IConnection connection, CancellationToken cancellationToken) в MongoDB.Driver.Core.Servers.Server.ServerChannel.ExecuteProtocol[TResult](IWireProtocol`1 protocol, CancellationToken cancellationToken) в MongoDB.Driver.Core.Servers.Server.ServerChannel.Command[TResult](DatabaseNamespace databaseNamespace, BsonDocument command, IElementNameValidator commandValidator, Func`1 responseHandling, Boolean slaveOk, IBsonSerializer`1 resultSerializer, MessageEncoderSettings messageEncoderSettings, CancellationToken cancellationToken) в MongoDB.Driver.Core.Operations.CommandOperationBase`1.ExecuteProtocol(IChannelHandle channel, ServerDescription serverDescription, ReadPreference readPreference, CancellationToken cancellationToken) в MongoDB.Driver.Core.Operations.CommandOperationBase`1.ExecuteProtocol(IChannelSource channelSource, ReadPreference readPreference, CancellationToken cancellationToken) в MongoDB.Driver.Core.Operations.ReadCommandOperation`1.Execute(IReadBinding binding, CancellationToken cancellationToken) в MongoDB.Driver.Core.Operations.DistinctOperation`1.Execute(IReadBinding binding, CancellationToken cancellationToken) в MongoDB.Driver.OperationExecutor.ExecuteReadOperation[TResult](IReadBinding binding, IReadOperation`1 operation, CancellationToken cancellationToken) в MongoDB.Driver.MongoCollectionImpl`1.ExecuteReadOperation[TResult](IReadOperation`1 operation, ReadPreference readPreference, CancellationToken cancellationToken) в MongoDB.Driver.MongoCollectionImpl`1.ExecuteReadOperation[TResult](IReadOperation`1 operation, CancellationToken cancellationToken) в MongoDB.Driver.MongoCollectionImpl`1.Distinct[TField](FieldDefinition`2 field, FilterDefinition`1 filter, DistinctOptions options, CancellationToken cancellationToken)
My use case is very simple and complies next example:
https://docs.mongodb.com/manual/reference/method/db.collection.distinct/#return-distinct-values-for-an-array-field
In my case I have a news collection. Each news can contain few tags. I want to select all unique tags from all news in collection. Next code block shows this situation (also see attachments).
[TestFixture] public class DistinctValuesForAnArrayFieldTest { [Test] public void ShouldDistinctValuesForAnArrayField() { // Given var mongoClientSettings = new MongoClientSettings { Server = new MongoServerAddress("localhost") }; var mongoClient = new MongoClient(mongoClientSettings); var mongoDatabase = mongoClient.GetDatabase("test"); var mongoCollection = mongoDatabase.GetCollection<News>("news"); mongoCollection.InsertMany(new[] { new News { Title = "News 1", Tags = new [] { "A", "B" } }, new News { Title = "News 2", Tags = new [] { "B", "C" } }, new News { Title = "News 3", Tags = new [] { "C", "D" } } }); // When // It works fine only for v2.4.0 and throws an exception for v2.4.1 // System.NotSupportedException : Values of type 'String' cannot be deserialized using a serializer of type 'CastingSerializer<String, IEnumerable<String>>'. var uniqueTags = mongoCollection.Distinct<string>("Tags", Builders<News>.Filter.Empty).ToList(); // Then CollectionAssert.AreEquivalent(new[] { "A", "B", "C", "D" }, uniqueTags); } } public class News { public string Title { get; set; } public IEnumerable<string> Tags { get; set; } }
Until 2.4.1 this code worked fine but not now. I noticed your changes in FieldValueSerializerHelper.cs and I think this bug relates with them. But anyway this bug relates with latest changes in the serialization mechanism.
If you know a correct way to get distinct items from array field which complies v2.4.1, please, let me know.
- related to
-
CSHARP-1884 In should still work when TField is not exactly right (like it used to)
- Closed
-
CSHARP-1890 Eq should still work when TField is not exactly right (like it used to)
- Closed
-
CSHARP-1893 New DistinctMany method which is like Distinct but for array fields.
- Closed