-
Type: Bug
-
Resolution: Fixed
-
Priority: Unknown
-
Affects Version/s: 2.24.0
-
Component/s: None
-
None
-
Fully Compatible
-
Dotnet Drivers
-
Not Needed
-
Summary
When attempting to project a calculated property of type decimal, the divide operator throws System.FormatException due to a TruncationException error.
System.FormatException HResult=0x80131537 Message=An error occurred while deserializing the GBP property of class <>f__AnonymousType0`2[[System.Decimal, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Decimal, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]: Truncation resulted in data loss. Source=MongoDB.Bson StackTrace: at MongoDB.Bson.Serialization.BsonClassMapSerializer`1.DeserializeMemberValue(BsonDeserializationContext context, BsonMemberMap memberMap) at MongoDB.Bson.Serialization.BsonClassMapSerializer`1.DeserializeClass(BsonDeserializationContext context) at MongoDB.Bson.Serialization.BsonClassMapSerializer`1.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) at MongoDB.Bson.Serialization.IBsonSerializerExtensions.Deserialize[TValue](IBsonSerializer`1 serializer, BsonDeserializationContext context) at MongoDB.Bson.Serialization.Serializers.EnumerableSerializerBase`2.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) at MongoDB.Bson.Serialization.IBsonSerializerExtensions.Deserialize[TValue](IBsonSerializer`1 serializer, BsonDeserializationContext context) at MongoDB.Driver.Core.Operations.AggregateOperation`1.CursorDeserializer.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) at MongoDB.Bson.Serialization.IBsonSerializerExtensions.Deserialize[TValue](IBsonSerializer`1 serializer, BsonDeserializationContext context) at MongoDB.Driver.Core.Operations.AggregateOperation`1.AggregateResultDeserializer.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) at MongoDB.Bson.Serialization.IBsonSerializerExtensions.Deserialize[TValue](IBsonSerializer`1 serializer, BsonDeserializationContext context) at MongoDB.Driver.Core.WireProtocol.CommandUsingCommandMessageWireProtocol`1.ProcessResponse(ConnectionId connectionId, CommandMessage responseMessage) at MongoDB.Driver.Core.WireProtocol.CommandUsingCommandMessageWireProtocol`1.Execute(IConnection connection, CancellationToken cancellationToken) at MongoDB.Driver.Core.WireProtocol.CommandWireProtocol`1.Execute(IConnection connection, CancellationToken cancellationToken) at MongoDB.Driver.Core.Servers.Server.ServerChannel.ExecuteProtocol[TResult](IWireProtocol`1 protocol, ICoreSession session, CancellationToken cancellationToken) at MongoDB.Driver.Core.Servers.Server.ServerChannel.Command[TResult](ICoreSession session, ReadPreference readPreference, DatabaseNamespace databaseNamespace, BsonDocument command, IEnumerable`1 commandPayloads, IElementNameValidator commandValidator, BsonDocument additionalOptions, Action`1 postWriteAction, CommandResponseHandling responseHandling, IBsonSerializer`1 resultSerializer, MessageEncoderSettings messageEncoderSettings, CancellationToken cancellationToken) at MongoDB.Driver.Core.Operations.CommandOperationBase`1.ExecuteProtocol(IChannelHandle channel, ICoreSessionHandle session, ReadPreference readPreference, CancellationToken cancellationToken) at MongoDB.Driver.Core.Operations.ReadCommandOperation`1.ExecuteAttempt(RetryableReadContext context, Int32 attempt, Nullable`1 transactionNumber, CancellationToken cancellationToken) at MongoDB.Driver.Core.Operations.RetryableReadOperationExecutor.Execute[TResult](IRetryableReadOperation`1 operation, RetryableReadContext context, CancellationToken cancellationToken) at MongoDB.Driver.Core.Operations.ReadCommandOperation`1.Execute(RetryableReadContext context, CancellationToken cancellationToken) at MongoDB.Driver.Core.Operations.AggregateOperation`1.Execute(RetryableReadContext context, CancellationToken cancellationToken) at MongoDB.Driver.Core.Operations.AggregateOperation`1.Execute(IReadBinding binding, CancellationToken cancellationToken) at MongoDB.Driver.OperationExecutor.ExecuteReadOperation[TResult](IReadBinding binding, IReadOperation`1 operation, CancellationToken cancellationToken) at MongoDB.Driver.MongoCollectionImpl`1.ExecuteReadOperation[TResult](IClientSessionHandle session, IReadOperation`1 operation, ReadPreference readPreference, CancellationToken cancellationToken) at MongoDB.Driver.MongoCollectionImpl`1.ExecuteReadOperation[TResult](IClientSessionHandle session, IReadOperation`1 operation, CancellationToken cancellationToken) at MongoDB.Driver.MongoCollectionImpl`1.Aggregate[TResult](IClientSessionHandle session, PipelineDefinition`2 pipeline, AggregateOptions options, CancellationToken cancellationToken) at MongoDB.Driver.MongoCollectionImpl`1.<>c__DisplayClass22_0`1.<Aggregate>b__0(IClientSessionHandle session) at MongoDB.Driver.MongoCollectionImpl`1.UsingImplicitSession[TResult](Func`2 func, CancellationToken cancellationToken) at MongoDB.Driver.MongoCollectionImpl`1.Aggregate[TResult](PipelineDefinition`2 pipeline, AggregateOptions options, CancellationToken cancellationToken) at MongoDB.Driver.CollectionAggregateFluent`2.ToCursor(CancellationToken cancellationToken) at MongoDB.Driver.IAsyncCursorSourceExtensions.ToList[TDocument](IAsyncCursorSource`1 source, CancellationToken cancellationToken) at Methods.ProjectWithDivideDecimal(IMongoCollection`1 items) in C:\Stuff\Documents\Programming\C#\Projects\MongoDbDivide\Program.cs:line 54 at Program.<Main>$(String[] args) in C:\Stuff\Documents\Programming\C#\Projects\MongoDbDivide\Program.cs:line 12 This exception was originally thrown at this call stack: [External Code]Inner Exception 1: TruncationException: Truncation resulted in data loss.
.NET 8.0
C# Driver Version = 2.24.0
MongoDB Server version = (Atlas) 6.0.14 , Region: AZURE California (westus)
How to Reproduce
-
dotnet new console --framework net8.0 dotnet add package MongoDB.Driver
- Paste the following code into the Program.cs file
using MongoDB.Bson.Serialization.Attributes; using MongoDB.Bson; using MongoDB.Driver; const string connectionUri = "<REDACTED>"; var client = new MongoClient(connectionUri); var db = client.GetDatabase("db"); var items = db.GetCollection<Item>("items"); await Methods.InsertOne(items); Methods.ProjectWithDivideDecimal(items); internal sealed class Item { public static Item SampleItem => new() { Balance = 1000 }; [BsonId] [BsonRepresentation(BsonType.ObjectId)] public string Id { get; set; } = string.Empty; [BsonElement("balance")] [BsonRepresentation(BsonType.Decimal128)] public decimal Balance { get; set; } public override string ToString() { return $"Id = {Id}, Balance = {Balance}"; } } internal static class Methods { public static async Task InsertOne(IMongoCollection<Item> items) { await items.InsertOneAsync(Item.SampleItem); } public static void ProjectWithDivideDecimal(IMongoCollection<Item> items) { var projectStage = Builders<Item>.Projection.Expression(a => new { a.Balance, GBP = a.Balance / 1.30M }); var aggr = items.Aggregate() .Project(projectStage); var results = aggr.ToList(); // TruncationException! results.ForEach(Console.WriteLine); } }
- Run
- You should see an exception thrown on this line:
var results = aggr.ToList();
Additional Background
I've attached a .zip file with the reproducible project.