-
Type: Bug
-
Resolution: Unresolved
-
Priority: Unknown
-
None
-
Affects Version/s: 2.23.1
-
Component/s: LINQ3
-
None
-
Dotnet Drivers
Summary
When using a $set pipeline stage to set the value of a nested document, an ExpressionNotSupportedException is thrown.
MongoDB.Driver version: 2.23.1
MongoDB version: MongoDB 7.0.2 Community
How to Reproduce
static void Test2(IMongoCollection<MyDocument> collection) { // Copy MyDocument.Value -> MyDocument.Nested.ValueCopy var update = Builders<MyDocument>.Update .Pipeline(new EmptyPipelineDefinition<MyDocument>() .Set(c => new MyDocument { Nested = new MyNestedDocument { ValueCopy = c.Value, }, })); collection.UpdateMany(Builders<MyDocument>.Filter.Empty, update); // throws ExpressionNotSupportedException }
class MyDocument { public int Id { get; set; } public string? Value { get; set; } public string? AnotherValue { get; set; } public MyNestedDocument? Nested { get; set; } } class MyNestedDocument { public string? ValueCopy { get; set; } }
Exception details:
MongoDB.Driver.Linq.ExpressionNotSupportedException HResult=0x80131515 Message=Expression not supported: new MyNestedDocument() {ValueCopy = c.Value} because member and value serializers are not compatible. Source=MongoDB.Driver StackTrace: at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToSetStageTranslators.ExpressionToSetStageTranslator.ThrowIfMemberAndValueSerializersAreNotCompatible(Expression expression, IBsonSerializer memberSerializer, IBsonSerializer valueSerializer) in /data/mci/1823813186d46f4153bdfc964eec49fd/mongo-csharp-driver/src/MongoDB.Driver/Linq/Linq3Implementation/Translators/ExpressionToSetStageTranslators/ExpressionToSetStageTranslator.cs:line 176 at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToSetStageTranslators.ExpressionToSetStageTranslator.CreateComputedField(TranslationContext context, IBsonDocumentSerializer documentSerializer, MemberInfo member, Expression valueExpression) in /data/mci/1823813186d46f4153bdfc964eec49fd/mongo-csharp-driver/src/MongoDB.Driver/Linq/Linq3Implementation/Translators/ExpressionToSetStageTranslators/ExpressionToSetStageTranslator.cs:line 157 at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToSetStageTranslators.ExpressionToSetStageTranslator.TranslateNewWithOptionalMemberInitializers(TranslationContext context, IBsonDocumentSerializer documentSerializer, MemberInitExpression memberInitExpression) in /data/mci/1823813186d46f4153bdfc964eec49fd/mongo-csharp-driver/src/MongoDB.Driver/Linq/Linq3Implementation/Translators/ExpressionToSetStageTranslators/ExpressionToSetStageTranslator.cs:line 131 at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToSetStageTranslators.ExpressionToSetStageTranslator.Translate(TranslationContext context, IBsonSerializer inputSerializer, LambdaExpression expression) in /data/mci/1823813186d46f4153bdfc964eec49fd/mongo-csharp-driver/src/MongoDB.Driver/Linq/Linq3Implementation/Translators/ExpressionToSetStageTranslators/ExpressionToSetStageTranslator.cs:line 44 at MongoDB.Driver.Linq.Linq3Implementation.LinqProviderAdapterV3.TranslateExpressionToSetStage[TDocument,TFields](Expression`1 expression, IBsonSerializer`1 documentSerializer, IBsonSerializerRegistry serializerRegistry) in /data/mci/1823813186d46f4153bdfc964eec49fd/mongo-csharp-driver/src/MongoDB.Driver/Linq/Linq3Implementation/LinqProviderAdapterV3.cs:line 190 at MongoDB.Driver.ExpressionSetFieldDefinitions`2.Render(IBsonSerializer`1 documentSerializer, IBsonSerializerRegistry serializerRegistry, LinqProvider linqProvider) in /data/mci/1823813186d46f4153bdfc964eec49fd/mongo-csharp-driver/src/MongoDB.Driver/SetFieldDefinitions.cs:line 100 at MongoDB.Driver.PipelineStageDefinitionBuilder.<>c__DisplayClass50_0`1.<Set>b__0(IBsonSerializer`1 inputSerializer, IBsonSerializerRegistry sr, LinqProvider linqProvider) in /data/mci/1823813186d46f4153bdfc964eec49fd/mongo-csharp-driver/src/MongoDB.Driver/PipelineStageDefinitionBuilder.cs:line 1531 at MongoDB.Driver.DelegatedPipelineStageDefinition`2.Render(IBsonSerializer`1 inputSerializer, IBsonSerializerRegistry serializerRegistry, LinqProvider linqProvider) in /data/mci/1823813186d46f4153bdfc964eec49fd/mongo-csharp-driver/src/MongoDB.Driver/PipelineStageDefinition.cs:line 439 at MongoDB.Driver.AppendedStagePipelineDefinition`3.Render(IBsonSerializer`1 inputSerializer, IBsonSerializerRegistry serializerRegistry, LinqProvider linqProvider) in /data/mci/1823813186d46f4153bdfc964eec49fd/mongo-csharp-driver/src/MongoDB.Driver/PipelineDefinitionBuilder.cs:line 1579 at MongoDB.Driver.PipelineUpdateDefinition`1.Render(IBsonSerializer`1 documentSerializer, IBsonSerializerRegistry serializerRegistry, LinqProvider linqProvider) in /data/mci/1823813186d46f4153bdfc964eec49fd/mongo-csharp-driver/src/MongoDB.Driver/UpdateDefinition.cs:line 132 at MongoDB.Driver.MongoCollectionImpl`1.ConvertWriteModelToWriteRequest(WriteModel`1 model, Int32 index) in /data/mci/1823813186d46f4153bdfc964eec49fd/mongo-csharp-driver/src/MongoDB.Driver/MongoCollectionImpl.cs:line 743 at System.Linq.Enumerable.<SelectIterator>d__229`2.MoveNext() in /_/src/libraries/System.Linq/src/System/Linq/Select.cs:line 96 at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) in /_/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs:line 85 at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source) in /_/src/libraries/System.Linq/src/System/Linq/ToCollection.cs:line 29 at MongoDB.Driver.Core.Operations.BulkMixedWriteOperation..ctor(CollectionNamespace collectionNamespace, IEnumerable`1 requests, MessageEncoderSettings messageEncoderSettings) in /data/mci/1823813186d46f4153bdfc964eec49fd/mongo-csharp-driver/src/MongoDB.Driver.Core/Core/Operations/BulkMixedWriteOperation.cs:line 61 at MongoDB.Driver.MongoCollectionImpl`1.CreateBulkWriteOperation(IClientSessionHandle session, IEnumerable`1 requests, BulkWriteOptions options) in /data/mci/1823813186d46f4153bdfc964eec49fd/mongo-csharp-driver/src/MongoDB.Driver/MongoCollectionImpl.cs:line 897 at MongoDB.Driver.MongoCollectionImpl`1.BulkWrite(IClientSessionHandle session, IEnumerable`1 requests, BulkWriteOptions options, CancellationToken cancellationToken) in /data/mci/1823813186d46f4153bdfc964eec49fd/mongo-csharp-driver/src/MongoDB.Driver/MongoCollectionImpl.cs:line 232 at MongoDB.Driver.MongoCollectionImpl`1.<>c__DisplayClass30_0.<BulkWrite>b__0(IClientSessionHandle session) in /data/mci/1823813186d46f4153bdfc964eec49fd/mongo-csharp-driver/src/MongoDB.Driver/MongoCollectionImpl.cs:line 214 at MongoDB.Driver.MongoCollectionImpl`1.UsingImplicitSession[TResult](Func`2 func, CancellationToken cancellationToken) in /data/mci/1823813186d46f4153bdfc964eec49fd/mongo-csharp-driver/src/MongoDB.Driver/MongoCollectionImpl.cs:line 1339 at MongoDB.Driver.MongoCollectionImpl`1.BulkWrite(IEnumerable`1 requests, BulkWriteOptions options, CancellationToken cancellationToken) in /data/mci/1823813186d46f4153bdfc964eec49fd/mongo-csharp-driver/src/MongoDB.Driver/MongoCollectionImpl.cs:line 214 at MongoDB.Driver.MongoCollectionBase`1.<>c__DisplayClass98_0.<UpdateMany>b__0(IEnumerable`1 requests, BulkWriteOptions bulkWriteOptions) in /data/mci/1823813186d46f4153bdfc964eec49fd/mongo-csharp-driver/src/MongoDB.Driver/MongoCollectionBase.cs:line 729 at MongoDB.Driver.MongoCollectionBase`1.UpdateMany(FilterDefinition`1 filter, UpdateDefinition`1 update, UpdateOptions options, Func`3 bulkWrite) in /data/mci/1823813186d46f4153bdfc964eec49fd/mongo-csharp-driver/src/MongoDB.Driver/MongoCollectionBase.cs:line 760 at MongoDB.Driver.MongoCollectionBase`1.UpdateMany(FilterDefinition`1 filter, UpdateDefinition`1 update, UpdateOptions options, CancellationToken cancellationToken) in /data/mci/1823813186d46f4153bdfc964eec49fd/mongo-csharp-driver/src/MongoDB.Driver/MongoCollectionBase.cs:line 729
Additional Background
The following works, since we are not dealing with a nested document:
static void Test(IMongoCollection<MyDocument> collection) { // Copy MyDocument.Value -> MyDocument.AnotherValue var update = Builders<MyDocument>.Update .Pipeline(new EmptyPipelineDefinition<MyDocument>() .Set(c => new MyDocument { AnotherValue = c.Value, })); collection.UpdateMany(Builders<MyDocument>.Filter.Empty, update); // Works }
The following works, and is what I'd expect the original method to be translated to:
static void Test3(IMongoCollection<MyDocument> collection) { // Copy MyDocument.Value -> MyDocument.Nested.ValueCopy var update = Builders<MyDocument>.Update .Pipeline(new EmptyPipelineDefinition<MyDocument>() .AppendStage<MyDocument, MyDocument, MyDocument>(new BsonDocument { ["$set"] = new BsonDocument { ["Nested"] = new BsonDocument { ["ValueCopy"] = "$Value", }, }, })); collection.UpdateMany(Builders<MyDocument>.Filter.Empty, update); // Works }