From eafd5ab69aa8fd906f99e5665b1b20125a4bcb25 Mon Sep 17 00:00:00 2001 From: rstam Date: Wed, 22 Oct 2025 15:57:25 -0400 Subject: [PATCH 1/5] CSHARP-1913: Support top-level SelectMany with Dictionary. --- .../Serializers/DictionarySerializerBase.cs | 23 ++- ...essionToAggregationExpressionTranslator.cs | 23 ++- .../SelectManyMethodToPipelineTranslator.cs | 22 ++- .../Jira/CSharp1913Tests.cs | 144 ++++++++++++++++++ 4 files changed, 191 insertions(+), 21 deletions(-) create mode 100644 tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/Jira/CSharp1913Tests.cs diff --git a/src/MongoDB.Bson/Serialization/Serializers/DictionarySerializerBase.cs b/src/MongoDB.Bson/Serialization/Serializers/DictionarySerializerBase.cs index 96b708d8aa6..3f6ff642bdd 100644 --- a/src/MongoDB.Bson/Serialization/Serializers/DictionarySerializerBase.cs +++ b/src/MongoDB.Bson/Serialization/Serializers/DictionarySerializerBase.cs @@ -499,21 +499,20 @@ obj is DictionarySerializerBase other && /// public bool TryGetItemSerializationInfo(out BsonSerializationInfo serializationInfo) { - if (_dictionaryRepresentation != DictionaryRepresentation.ArrayOfDocuments) + if (_dictionaryRepresentation is DictionaryRepresentation.ArrayOfArrays or DictionaryRepresentation.ArrayOfDocuments) { - serializationInfo = null; - return false; + var representation = _dictionaryRepresentation == DictionaryRepresentation.ArrayOfArrays + ? BsonType.Array + : BsonType.Document; + var keySerializer = _lazyKeySerializer.Value; + var valueSerializer = _lazyValueSerializer.Value; + var keyValuePairSerializer = new KeyValuePairSerializer(representation, keySerializer, valueSerializer); + serializationInfo = new BsonSerializationInfo(null, keyValuePairSerializer, keyValuePairSerializer.ValueType); + return true; } - var serializer = new KeyValuePairSerializer( - BsonType.Document, - _lazyKeySerializer.Value, - _lazyValueSerializer.Value); - serializationInfo = new BsonSerializationInfo( - null, - serializer, - serializer.ValueType); - return true; + serializationInfo = null; + return false; } /// diff --git a/src/MongoDB.Driver/Linq/Linq3Implementation/Translators/ExpressionToAggregationExpressionTranslators/ExpressionToAggregationExpressionTranslator.cs b/src/MongoDB.Driver/Linq/Linq3Implementation/Translators/ExpressionToAggregationExpressionTranslators/ExpressionToAggregationExpressionTranslator.cs index c2d8e0010e9..4bfac344596 100644 --- a/src/MongoDB.Driver/Linq/Linq3Implementation/Translators/ExpressionToAggregationExpressionTranslators/ExpressionToAggregationExpressionTranslator.cs +++ b/src/MongoDB.Driver/Linq/Linq3Implementation/Translators/ExpressionToAggregationExpressionTranslators/ExpressionToAggregationExpressionTranslator.cs @@ -16,7 +16,9 @@ using System; using System.Linq; using System.Linq.Expressions; +using MongoDB.Bson; using MongoDB.Bson.Serialization; +using MongoDB.Bson.Serialization.Options; using MongoDB.Bson.Serialization.Serializers; using MongoDB.Driver.Linq.Linq3Implementation.Ast.Expressions; using MongoDB.Driver.Linq.Linq3Implementation.Misc; @@ -95,15 +97,28 @@ public static TranslatedExpression TranslateEnumerable(TranslationContext contex { var aggregateExpression = Translate(context, expression); - var serializer = aggregateExpression.Serializer; - if (serializer is IWrappedEnumerableSerializer wrappedEnumerableSerializer) + if (aggregateExpression.Serializer is IWrappedEnumerableSerializer wrappedEnumerableSerializer) { var enumerableFieldName = wrappedEnumerableSerializer.EnumerableFieldName; var enumerableElementSerializer = wrappedEnumerableSerializer.EnumerableElementSerializer; - var enumerableSerializer = IEnumerableSerializer.Create(enumerableElementSerializer); + var ast = AstExpression.GetField(aggregateExpression.Ast, enumerableFieldName); + var ienumerableSerializer = IEnumerableSerializer.Create(enumerableElementSerializer); + + aggregateExpression = new TranslatedExpression(expression, ast, ienumerableSerializer); + } + + if (aggregateExpression.Serializer is IBsonDictionarySerializer dictionarySerializer && + dictionarySerializer.DictionaryRepresentation == DictionaryRepresentation.Document) + { + var keySerializer = dictionarySerializer.KeySerializer; + var valueSerializer = dictionarySerializer.ValueSerializer; + var keyValuePairSerializer = KeyValuePairSerializer.Create(BsonType.Document, keySerializer, valueSerializer); + + var ast = AstExpression.ObjectToArray(aggregateExpression.Ast); + var ienumerableSerializer = ArraySerializerHelper.CreateSerializer(keyValuePairSerializer); - return new TranslatedExpression(aggregateExpression.Expression, ast, enumerableSerializer); + aggregateExpression = new TranslatedExpression(expression, ast, ienumerableSerializer); } return aggregateExpression; diff --git a/src/MongoDB.Driver/Linq/Linq3Implementation/Translators/ExpressionToPipelineTranslators/SelectManyMethodToPipelineTranslator.cs b/src/MongoDB.Driver/Linq/Linq3Implementation/Translators/ExpressionToPipelineTranslators/SelectManyMethodToPipelineTranslator.cs index 309c7a2e5fa..c90f7796140 100644 --- a/src/MongoDB.Driver/Linq/Linq3Implementation/Translators/ExpressionToPipelineTranslators/SelectManyMethodToPipelineTranslator.cs +++ b/src/MongoDB.Driver/Linq/Linq3Implementation/Translators/ExpressionToPipelineTranslators/SelectManyMethodToPipelineTranslator.cs @@ -14,8 +14,13 @@ */ using System.Collections.ObjectModel; +using System.Linq; using System.Linq.Expressions; using System.Reflection; +using MongoDB.Bson; +using MongoDB.Bson.Serialization; +using MongoDB.Bson.Serialization.Options; +using MongoDB.Bson.Serialization.Serializers; using MongoDB.Driver.Linq.Linq3Implementation.Ast; using MongoDB.Driver.Linq.Linq3Implementation.Ast.Expressions; using MongoDB.Driver.Linq.Linq3Implementation.Ast.Stages; @@ -74,16 +79,23 @@ private static TranslatedPipeline TranslateSelectMany( { var sourceSerializer = pipeline.OutputSerializer; var selectorLambda = ExpressionHelper.UnquoteLambda(arguments[1]); - var selectorTranslation = ExpressionToAggregationExpressionTranslator.TranslateLambdaBody(context, selectorLambda, sourceSerializer, asRoot: true); - var resultValueSerializer = ArraySerializerHelper.GetItemSerializer(selectorTranslation.Serializer); - var resultWrappedValueSerializer = WrappedValueSerializer.Create("_v", resultValueSerializer); + var selectorParameter = selectorLambda.Parameters.Single(); + var selectorParameterSymbol = context.CreateSymbol(selectorParameter, sourceSerializer, isCurrent: true); + var selectorContext = context.WithSymbol(selectorParameterSymbol); + var selectorTranslation = ExpressionToAggregationExpressionTranslator.TranslateEnumerable(selectorContext, selectorLambda.Body); + + var valuesAst = selectorTranslation.Ast; + var valuesSerializer = selectorTranslation.Serializer; + + var valuesItemSerializer = ArraySerializerHelper.GetItemSerializer(valuesSerializer); + var wrappedValueSerializer = WrappedValueSerializer.Create("_v", valuesItemSerializer); pipeline = pipeline.AddStages( AstStage.Project( - AstProject.Set("_v", selectorTranslation.Ast), + AstProject.Set("_v", valuesAst), AstProject.ExcludeId()), AstStage.Unwind("_v"), - resultWrappedValueSerializer); + wrappedValueSerializer); return pipeline; } diff --git a/tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/Jira/CSharp1913Tests.cs b/tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/Jira/CSharp1913Tests.cs new file mode 100644 index 00000000000..1c8d1fd63f6 --- /dev/null +++ b/tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/Jira/CSharp1913Tests.cs @@ -0,0 +1,144 @@ +/* Copyright 2010-present MongoDB Inc. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +using System.Collections.Generic; +using System.Linq; +using MongoDB.Driver.TestHelpers; +using FluentAssertions; +using MongoDB.Bson.Serialization.Attributes; +using MongoDB.Bson.Serialization.Options; +using Xunit; + +namespace MongoDB.Driver.Tests.Linq.Linq3Implementation.Jira; + +public class CSharp1913Tests : LinqIntegrationTest +{ + public CSharp1913Tests(ClassFixture fixture) + : base(fixture) + { + } + + [Fact] + public void SelectMany_with_ArrayOfArrays_representation_should_work() + { + var collection = Fixture.Collection; + + var queryable = collection.AsQueryable() + .OfType() + .Where( to => to.Name == "TestName" ) + .SelectMany( to => to.DictionaryWithArrayOfArraysRepresentation ); + + var stages = Translate(collection, queryable); + AssertStages( + stages, + "{ $match : { Name : 'TestName' } }", + "{ $project : { _v : '$DictionaryWithArrayOfArraysRepresentation', _id : 0 } }", + "{ $unwind : '$_v' }"); + + var results = queryable.ToList(); + results.Count.Should().Be(3); + results[0].Key.Should().Be("A"); + results[0].Value.Should().Be("a"); + results[1].Key.Should().Be("B"); + results[1].Value.Should().Be("b"); + results[2].Key.Should().Be("C"); + results[2].Value.Should().Be("c"); + } + + [Fact] + public void SelectMany_with_ArrayOfDocuments_representation_should_work() + { + var collection = Fixture.Collection; + + var queryable = collection.AsQueryable() + .OfType() + .Where( to => to.Name == "TestName" ) + .SelectMany( to => to.DictionaryWithArrayOfDocumentsRepresentation ); + + var stages = Translate(collection, queryable); + AssertStages( + stages, + "{ $match : { Name : 'TestName' } }", + "{ $project : { _v : '$DictionaryWithArrayOfDocumentsRepresentation', _id : 0 } }", + "{ $unwind : '$_v' }"); + + var results = queryable.ToList(); + results.Count.Should().Be(3); + results[0].Key.Should().Be("A"); + results[0].Value.Should().Be("a"); + results[1].Key.Should().Be("B"); + results[1].Value.Should().Be("b"); + results[2].Key.Should().Be("C"); + results[2].Value.Should().Be("c"); + } + + [Fact] + public void SelectMany_with_Document_representation_should_work() + { + var collection = Fixture.Collection; + + var queryable = collection.AsQueryable() + .OfType() + .Where( to => to.Name == "TestName" ) + .SelectMany( to => to.DictionaryWithDocumentRepresentation); + + var stages = Translate(collection, queryable); + AssertStages( + stages, + "{ $match : { Name : 'TestName' } }", + "{ $project : { _v : { $objectToArray : '$DictionaryWithDocumentRepresentation' }, _id : 0 } }", + "{ $unwind : '$_v' }"); + + var results = queryable.ToList(); + results.Count.Should().Be(3); + results[0].Key.Should().Be("A"); + results[0].Value.Should().Be("a"); + results[1].Key.Should().Be("B"); + results[1].Value.Should().Be("b"); + results[2].Key.Should().Be("C"); + results[2].Value.Should().Be("c"); + } + + public class C + { + public int Id { get; set; } + public string Name {get;set;} + + [BsonDictionaryOptions( DictionaryRepresentation.ArrayOfArrays )] + public Dictionary DictionaryWithArrayOfArraysRepresentation { get; set; } = new Dictionary(); + + + [BsonDictionaryOptions( DictionaryRepresentation.ArrayOfDocuments )] + public Dictionary DictionaryWithArrayOfDocumentsRepresentation { get; set; } = new Dictionary(); + + [BsonDictionaryOptions( DictionaryRepresentation.Document )] + public Dictionary DictionaryWithDocumentRepresentation { get; set; } = new Dictionary(); + } + + public sealed class ClassFixture : MongoCollectionFixture + { + protected override IEnumerable InitialData => + [ + new C + { + Id = 1, + Name = "TestName", + DictionaryWithArrayOfArraysRepresentation = new Dictionary { { "A", "a" }, { "B", "b" }, { "C", "c" } }, + DictionaryWithArrayOfDocumentsRepresentation = new Dictionary { { "A", "a" }, { "B", "b" }, { "C", "c" } }, + DictionaryWithDocumentRepresentation = new Dictionary { { "A", "a" }, { "B", "b" }, { "C", "c" } }, + } + ]; + } +} From 2cf31c28eac9ea2331aa8d1bd2748c48240327ab Mon Sep 17 00:00:00 2001 From: rstam Date: Wed, 22 Oct 2025 16:37:49 -0400 Subject: [PATCH 2/5] CSHARP-1913: Verify that this fixes CSHARP-4251 also. --- .../Jira/CSharp4251Tests.cs | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/Jira/CSharp4251Tests.cs diff --git a/tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/Jira/CSharp4251Tests.cs b/tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/Jira/CSharp4251Tests.cs new file mode 100644 index 00000000000..49b9ba2f59d --- /dev/null +++ b/tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/Jira/CSharp4251Tests.cs @@ -0,0 +1,77 @@ +/* Copyright 2010-present MongoDB Inc. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +using System.Collections.Generic; +using System.Linq; +using MongoDB.Driver.TestHelpers; +using FluentAssertions; +using Xunit; + +namespace MongoDB.Driver.Tests.Linq.Linq3Implementation.Jira; + +public class CSharp4251Tests : LinqIntegrationTest +{ + public CSharp4251Tests(ClassFixture fixture) + : base(fixture) + { + } + + [Fact] + public void Test1() + { + var collection = Fixture.Collection; + + var queryable = collection.AsQueryable() + .Select(n => + new MappedObject { Items = n.Items.Select(k => new KeyValuedObject() { Count = k.Value.Count, Description = k.Value.Description, Name = k.Key }).ToList() } + ); + + var stages = Translate(collection, queryable); + AssertStages(stages, "{ $project : { Items : { $map : { input : { $objectToArray : '$Items' }, as : 'k', in : { Count : '$$k.v.Count', Description : '$$k.v.Description', Name : '$$k.k' } } }, _id : 0 } }"); + } + + public class DatabaseObject + { + public int Id { get; set; } + public Dictionary Items { get; set; } = new Dictionary(); + + } + + public class DatabaseValueObject + { + public string Description { get; set; } = string.Empty; + public int Count { get; set; } + } + + public class MappedObject + { + public List Items { get; set; } = new List(); + } + + public class KeyValuedObject + { + public string Name { get; set; } = string.Empty; + public int Count { get; set; } + public string Description { get; set; } = string.Empty; + } + + public sealed class ClassFixture : MongoCollectionFixture + { + protected override IEnumerable InitialData => null; + // [ + // new DatabaseObject { } + // ]; + } +} From 27d21ba58cd25092b8ce244d1bc469341e10b85b Mon Sep 17 00:00:00 2001 From: rstam Date: Thu, 23 Oct 2025 11:29:46 -0400 Subject: [PATCH 3/5] CSHARP-1913: Added tests for nested SelectMany. --- .../Jira/CSharp1913Tests.cs | 66 ++++++++++++++++++- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/Jira/CSharp1913Tests.cs b/tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/Jira/CSharp1913Tests.cs index 1c8d1fd63f6..bac80a623bc 100644 --- a/tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/Jira/CSharp1913Tests.cs +++ b/tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/Jira/CSharp1913Tests.cs @@ -31,7 +31,67 @@ public CSharp1913Tests(ClassFixture fixture) } [Fact] - public void SelectMany_with_ArrayOfArrays_representation_should_work() + public void Nested__SelectMany_with_ArrayOfArrays_representation_should_work() + { + var collection = Fixture.Collection; + + var queryable = collection.AsQueryable() + .OfType() + .Where( to => to.Name == "TestName" ) + .Select( to => to.DictionaryWithArrayOfArraysRepresentation.SelectMany(kvp => new KeyValuePair[] { kvp }) ); + + var stages = Translate(collection, queryable); + AssertStages( + stages, + "{ $match : { Name : 'TestName' } }", + "{ $project : { _v : { $reduce : { input : { $map : { input : '$DictionaryWithArrayOfArraysRepresentation', as : 'kvp', in : ['$$kvp'] } }, initialValue : [], in : { $concatArrays : ['$$value', '$$this'] } } }, _id : 0 } }"); + + var result = queryable.Single(); + result.Select(kvp => kvp.Key).Should().Equal("A", "B", "C"); + } + + [Fact] + public void Nested__SelectMany_with_ArrayOfDocuments_representation_should_work() + { + var collection = Fixture.Collection; + + var queryable = collection.AsQueryable() + .OfType() + .Where( to => to.Name == "TestName" ) + .Select( to => to.DictionaryWithArrayOfDocumentsRepresentation.SelectMany(kvp => new KeyValuePair[] { kvp }) ); + + var stages = Translate(collection, queryable); + AssertStages( + stages, + "{ $match : { Name : 'TestName' } }", + "{ $project : { _v : { $reduce : { input : { $map : { input : '$DictionaryWithArrayOfDocumentsRepresentation', as : 'kvp', in : ['$$kvp'] } }, initialValue : [], in : { $concatArrays : ['$$value', '$$this'] } } }, _id : 0 } }"); + + var result = queryable.Single(); + result.Select(kvp => kvp.Key).Should().Equal("A", "B", "C"); + } + + [Fact] + public void Nested_SelectMany_with_Document_representation_should_work() + { + var collection = Fixture.Collection; + + var queryable = collection.AsQueryable() + .OfType() + .Where( to => to.Name == "TestName" ) + .Select( to => to.DictionaryWithDocumentRepresentation.SelectMany(kvp => new KeyValuePair[] { kvp }) ); + + var stages = Translate(collection, queryable); + AssertStages( + stages, + "{ $match : { Name : 'TestName' } }", + "{ $project : { _v : { $reduce : { input : { $map : { input : { $objectToArray : '$DictionaryWithDocumentRepresentation' }, as : 'kvp', in : ['$$kvp'] } }, initialValue : [], in : { $concatArrays : ['$$value', '$$this'] } } }, _id : 0 } }"); + + var result = queryable.Single(); + result.Select(kvp => kvp.Key).Should().Equal("A", "B", "C"); + } + + [Fact] + public void Top_level_SelectMany_with_ArrayOfArrays_representation_should_work() { var collection = Fixture.Collection; @@ -58,7 +118,7 @@ public void SelectMany_with_ArrayOfArrays_representation_should_work() } [Fact] - public void SelectMany_with_ArrayOfDocuments_representation_should_work() + public void Top_level_SelectMany_with_ArrayOfDocuments_representation_should_work() { var collection = Fixture.Collection; @@ -85,7 +145,7 @@ public void SelectMany_with_ArrayOfDocuments_representation_should_work() } [Fact] - public void SelectMany_with_Document_representation_should_work() + public void Top_level_SelectMany_with_Document_representation_should_work() { var collection = Fixture.Collection; From 60558b72cfc61c1c29861fec1d1e87dac0bb2b67 Mon Sep 17 00:00:00 2001 From: rstam Date: Thu, 23 Oct 2025 15:00:53 -0400 Subject: [PATCH 4/5] CSHARP-1913: Requested changes. --- .../Jira/CSharp1913Tests.cs | 30 ++++---- .../Jira/CSharp4251Tests.cs | 77 ------------------- 2 files changed, 15 insertions(+), 92 deletions(-) delete mode 100644 tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/Jira/CSharp4251Tests.cs diff --git a/tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/Jira/CSharp1913Tests.cs b/tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/Jira/CSharp1913Tests.cs index bac80a623bc..565dba2a71b 100644 --- a/tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/Jira/CSharp1913Tests.cs +++ b/tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/Jira/CSharp1913Tests.cs @@ -37,8 +37,8 @@ public void Nested__SelectMany_with_ArrayOfArrays_representation_should_work() var queryable = collection.AsQueryable() .OfType() - .Where( to => to.Name == "TestName" ) - .Select( to => to.DictionaryWithArrayOfArraysRepresentation.SelectMany(kvp => new KeyValuePair[] { kvp }) ); + .Where(to => to.Name == "TestName") + .Select(to => to.DictionaryWithArrayOfArraysRepresentation.SelectMany(kvp => new KeyValuePair[] { kvp })); var stages = Translate(collection, queryable); AssertStages( @@ -57,8 +57,8 @@ public void Nested__SelectMany_with_ArrayOfDocuments_representation_should_work( var queryable = collection.AsQueryable() .OfType() - .Where( to => to.Name == "TestName" ) - .Select( to => to.DictionaryWithArrayOfDocumentsRepresentation.SelectMany(kvp => new KeyValuePair[] { kvp }) ); + .Where(to => to.Name == "TestName") + .Select(to => to.DictionaryWithArrayOfDocumentsRepresentation.SelectMany(kvp => new KeyValuePair[] { kvp })); var stages = Translate(collection, queryable); AssertStages( @@ -77,8 +77,8 @@ public void Nested_SelectMany_with_Document_representation_should_work() var queryable = collection.AsQueryable() .OfType() - .Where( to => to.Name == "TestName" ) - .Select( to => to.DictionaryWithDocumentRepresentation.SelectMany(kvp => new KeyValuePair[] { kvp }) ); + .Where(to => to.Name == "TestName") + .Select(to => to.DictionaryWithDocumentRepresentation.SelectMany(kvp => new KeyValuePair[] { kvp })); var stages = Translate(collection, queryable); AssertStages( @@ -97,8 +97,8 @@ public void Top_level_SelectMany_with_ArrayOfArrays_representation_should_work() var queryable = collection.AsQueryable() .OfType() - .Where( to => to.Name == "TestName" ) - .SelectMany( to => to.DictionaryWithArrayOfArraysRepresentation ); + .Where(to => to.Name == "TestName") + .SelectMany(to => to.DictionaryWithArrayOfArraysRepresentation); var stages = Translate(collection, queryable); AssertStages( @@ -124,8 +124,8 @@ public void Top_level_SelectMany_with_ArrayOfDocuments_representation_should_wor var queryable = collection.AsQueryable() .OfType() - .Where( to => to.Name == "TestName" ) - .SelectMany( to => to.DictionaryWithArrayOfDocumentsRepresentation ); + .Where(to => to.Name == "TestName") + .SelectMany(to => to.DictionaryWithArrayOfDocumentsRepresentation); var stages = Translate(collection, queryable); AssertStages( @@ -151,8 +151,8 @@ public void Top_level_SelectMany_with_Document_representation_should_work() var queryable = collection.AsQueryable() .OfType() - .Where( to => to.Name == "TestName" ) - .SelectMany( to => to.DictionaryWithDocumentRepresentation); + .Where(to => to.Name == "TestName") + .SelectMany(to => to.DictionaryWithDocumentRepresentation); var stages = Translate(collection, queryable); AssertStages( @@ -176,14 +176,14 @@ public class C public int Id { get; set; } public string Name {get;set;} - [BsonDictionaryOptions( DictionaryRepresentation.ArrayOfArrays )] + [BsonDictionaryOptions(DictionaryRepresentation.ArrayOfArrays)] public Dictionary DictionaryWithArrayOfArraysRepresentation { get; set; } = new Dictionary(); - [BsonDictionaryOptions( DictionaryRepresentation.ArrayOfDocuments )] + [BsonDictionaryOptions(DictionaryRepresentation.ArrayOfDocuments)] public Dictionary DictionaryWithArrayOfDocumentsRepresentation { get; set; } = new Dictionary(); - [BsonDictionaryOptions( DictionaryRepresentation.Document )] + [BsonDictionaryOptions(DictionaryRepresentation.Document)] public Dictionary DictionaryWithDocumentRepresentation { get; set; } = new Dictionary(); } diff --git a/tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/Jira/CSharp4251Tests.cs b/tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/Jira/CSharp4251Tests.cs deleted file mode 100644 index 49b9ba2f59d..00000000000 --- a/tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/Jira/CSharp4251Tests.cs +++ /dev/null @@ -1,77 +0,0 @@ -/* Copyright 2010-present MongoDB Inc. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -using System.Collections.Generic; -using System.Linq; -using MongoDB.Driver.TestHelpers; -using FluentAssertions; -using Xunit; - -namespace MongoDB.Driver.Tests.Linq.Linq3Implementation.Jira; - -public class CSharp4251Tests : LinqIntegrationTest -{ - public CSharp4251Tests(ClassFixture fixture) - : base(fixture) - { - } - - [Fact] - public void Test1() - { - var collection = Fixture.Collection; - - var queryable = collection.AsQueryable() - .Select(n => - new MappedObject { Items = n.Items.Select(k => new KeyValuedObject() { Count = k.Value.Count, Description = k.Value.Description, Name = k.Key }).ToList() } - ); - - var stages = Translate(collection, queryable); - AssertStages(stages, "{ $project : { Items : { $map : { input : { $objectToArray : '$Items' }, as : 'k', in : { Count : '$$k.v.Count', Description : '$$k.v.Description', Name : '$$k.k' } } }, _id : 0 } }"); - } - - public class DatabaseObject - { - public int Id { get; set; } - public Dictionary Items { get; set; } = new Dictionary(); - - } - - public class DatabaseValueObject - { - public string Description { get; set; } = string.Empty; - public int Count { get; set; } - } - - public class MappedObject - { - public List Items { get; set; } = new List(); - } - - public class KeyValuedObject - { - public string Name { get; set; } = string.Empty; - public int Count { get; set; } - public string Description { get; set; } = string.Empty; - } - - public sealed class ClassFixture : MongoCollectionFixture - { - protected override IEnumerable InitialData => null; - // [ - // new DatabaseObject { } - // ]; - } -} From 867ab5c8a19b92ff94ef22220b71621f5163399a Mon Sep 17 00:00:00 2001 From: rstam Date: Thu, 23 Oct 2025 19:14:46 -0400 Subject: [PATCH 5/5] CSHARP-1913: Removed extra blank line. --- .../Linq/Linq3Implementation/Jira/CSharp1913Tests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/Jira/CSharp1913Tests.cs b/tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/Jira/CSharp1913Tests.cs index 565dba2a71b..0e5bc7f1c2d 100644 --- a/tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/Jira/CSharp1913Tests.cs +++ b/tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/Jira/CSharp1913Tests.cs @@ -179,7 +179,6 @@ public class C [BsonDictionaryOptions(DictionaryRepresentation.ArrayOfArrays)] public Dictionary DictionaryWithArrayOfArraysRepresentation { get; set; } = new Dictionary(); - [BsonDictionaryOptions(DictionaryRepresentation.ArrayOfDocuments)] public Dictionary DictionaryWithArrayOfDocumentsRepresentation { get; set; } = new Dictionary();