diff --git a/src/MongoDB.Driver/FindFluent.cs b/src/MongoDB.Driver/FindFluent.cs index b0027fdc34d..760549c5e31 100644 --- a/src/MongoDB.Driver/FindFluent.cs +++ b/src/MongoDB.Driver/FindFluent.cs @@ -197,7 +197,7 @@ public override string ToString() if (_options.Projection != null) { - var renderedProjection = Render(_options.Projection.Render); + var renderedProjection = Render(_options.Projection.RenderForFind); if (renderedProjection.Document != null) { sb.Append(", " + renderedProjection.Document.ToString()); diff --git a/src/MongoDB.Driver/IFindFluentExtensions.cs b/src/MongoDB.Driver/IFindFluentExtensions.cs index 42ba7edae32..deb24dc5f6c 100644 --- a/src/MongoDB.Driver/IFindFluentExtensions.cs +++ b/src/MongoDB.Driver/IFindFluentExtensions.cs @@ -14,12 +14,10 @@ */ using System; -using System.Linq; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; using MongoDB.Bson; -using MongoDB.Bson.Serialization; using MongoDB.Driver.Core.Misc; namespace MongoDB.Driver @@ -59,7 +57,7 @@ public static IFindFluent Project(new FindExpressionProjectionDefinition(projection)); + return find.Project(new ExpressionProjectionDefinition(projection, null)); } /// @@ -75,7 +73,7 @@ public static IOrderedFindFluent SortBy + // We require an implementation of IFindFluent // to also implement IOrderedFindFluent return (IOrderedFindFluent)find.Sort( new DirectionalSortDefinition(new ExpressionFieldDefinition(field), SortDirection.Ascending)); @@ -94,7 +92,7 @@ public static IOrderedFindFluent SortByDescending + // We require an implementation of IFindFluent // to also implement IOrderedFindFluent return (IOrderedFindFluent)find.Sort( new DirectionalSortDefinition(new ExpressionFieldDefinition(field), SortDirection.Descending)); diff --git a/src/MongoDB.Driver/Linq/Linq3Implementation/Ast/Optimizers/AstFindProjectionSimplifier.cs b/src/MongoDB.Driver/Linq/Linq3Implementation/Ast/Optimizers/AstFindProjectionSimplifier.cs new file mode 100644 index 00000000000..6d9d3240a27 --- /dev/null +++ b/src/MongoDB.Driver/Linq/Linq3Implementation/Ast/Optimizers/AstFindProjectionSimplifier.cs @@ -0,0 +1,37 @@ +/* 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 MongoDB.Driver.Linq.Linq3Implementation.Ast.Expressions; +using MongoDB.Driver.Linq.Linq3Implementation.Ast.Stages; + +namespace MongoDB.Driver.Linq.Linq3Implementation.Ast.Optimizers +{ + internal class AstFindProjectionSimplifier : AstSimplifier + { + public override AstNode VisitProjectStageSetFieldSpecification(AstProjectStageSetFieldSpecification node) + { + node = (AstProjectStageSetFieldSpecification)base.VisitProjectStageSetFieldSpecification(node); + + // { path : '$path' } => { path : 1 } + if (node.Value is AstFieldPathExpression fieldPathExpression && + fieldPathExpression.Path == $"${node.Path}") + { + return AstProject.Include(node.Path); + } + + return node; + } + } +} diff --git a/src/MongoDB.Driver/Linq/Linq3Implementation/Ast/Optimizers/AstSimplifier.cs b/src/MongoDB.Driver/Linq/Linq3Implementation/Ast/Optimizers/AstSimplifier.cs index a0fee265e7e..3e4d72745fe 100644 --- a/src/MongoDB.Driver/Linq/Linq3Implementation/Ast/Optimizers/AstSimplifier.cs +++ b/src/MongoDB.Driver/Linq/Linq3Implementation/Ast/Optimizers/AstSimplifier.cs @@ -307,20 +307,6 @@ static AstExpression UltimateGetFieldInput(AstGetFieldExpression getField) } } - public override AstNode VisitProjectStageSetFieldSpecification(AstProjectStageSetFieldSpecification node) - { - node = (AstProjectStageSetFieldSpecification)base.VisitProjectStageSetFieldSpecification(node); - - // { path : '$path' } => { path : 1 } - if (node.Value is AstFieldPathExpression fieldPathExpression && - fieldPathExpression.Path == $"${node.Path}") - { - return AstProject.Include(node.Path); - } - - return node; - } - public override AstNode VisitUnaryExpression(AstUnaryExpression node) { // { $first : } => { $arrayElemAt : [, 0] } (or -1 for $last) diff --git a/src/MongoDB.Driver/Linq/Linq3Implementation/LinqProviderAdapterV3.cs b/src/MongoDB.Driver/Linq/Linq3Implementation/LinqProviderAdapterV3.cs index dc68fe48dbd..1c03c09586c 100644 --- a/src/MongoDB.Driver/Linq/Linq3Implementation/LinqProviderAdapterV3.cs +++ b/src/MongoDB.Driver/Linq/Linq3Implementation/LinqProviderAdapterV3.cs @@ -139,9 +139,7 @@ internal override RenderedProjectionDefinition TranslateExpressionT Expression> expression, IBsonSerializer sourceSerializer, IBsonSerializerRegistry serializerRegistry) - { - return TranslateExpressionToProjection(expression, sourceSerializer, serializerRegistry, translationOptions: null); - } + => TranslateExpressionToProjectionInternal(expression, sourceSerializer, new AstFindProjectionSimplifier()); internal override RenderedProjectionDefinition TranslateExpressionToGroupProjection( Expression> idExpression, @@ -158,12 +156,18 @@ internal override RenderedProjectionDefinition TranslateExpressionToPro IBsonSerializer inputSerializer, IBsonSerializerRegistry serializerRegistry, ExpressionTranslationOptions translationOptions) + => TranslateExpressionToProjectionInternal(expression, inputSerializer, new AstSimplifier()); + + private RenderedProjectionDefinition TranslateExpressionToProjectionInternal( + Expression> expression, + IBsonSerializer inputSerializer, + AstSimplifier simplifier) { expression = (Expression>)PartialEvaluator.EvaluatePartially(expression); var context = TranslationContext.Create(expression, inputSerializer); var translation = ExpressionToAggregationExpressionTranslator.TranslateLambdaBody(context, expression, inputSerializer, asRoot: true); var (projectStage, projectionSerializer) = ProjectionHelper.CreateProjectStage(translation); - var simplifiedProjectStage = AstSimplifier.Simplify(projectStage); + var simplifiedProjectStage = simplifier.Visit(projectStage); var renderedProjection = simplifiedProjectStage.Render().AsBsonDocument["$project"].AsBsonDocument; return new RenderedProjectionDefinition(renderedProjection, (IBsonSerializer)projectionSerializer); diff --git a/src/MongoDB.Driver/MongoCollectionImpl.cs b/src/MongoDB.Driver/MongoCollectionImpl.cs index c16f82bbc4d..5284c4cd78a 100644 --- a/src/MongoDB.Driver/MongoCollectionImpl.cs +++ b/src/MongoDB.Driver/MongoCollectionImpl.cs @@ -1059,7 +1059,7 @@ private FindOneAndUpdateOperation CreateFindOneAndUpdateOperation CreateFindOperation(FilterDefinition filter, FindOptions options) { var projection = options.Projection ?? new ClientSideDeserializationProjectionDefinition(); - var renderedProjection = projection.Render(_documentSerializer, _settings.SerializerRegistry, _linqProvider); + var renderedProjection = projection.RenderForFind(_documentSerializer, _settings.SerializerRegistry, _linqProvider); return new FindOperation( _collectionNamespace, diff --git a/src/MongoDB.Driver/PipelineStageDefinitionBuilder.cs b/src/MongoDB.Driver/PipelineStageDefinitionBuilder.cs index 49d1b126939..636345d6413 100644 --- a/src/MongoDB.Driver/PipelineStageDefinitionBuilder.cs +++ b/src/MongoDB.Driver/PipelineStageDefinitionBuilder.cs @@ -1305,7 +1305,7 @@ public static PipelineStageDefinition Project( ExpressionTranslationOptions translationOptions = null) { Ensure.IsNotNull(projection, nameof(projection)); - return Project(new ProjectExpressionProjection(projection, translationOptions)); + return Project(new ExpressionProjectionDefinition(projection, translationOptions)); } /// @@ -1905,6 +1905,11 @@ public override RenderedProjectionDefinition Render(IBsonSerializer RenderForFind(IBsonSerializer sourceSerializer, IBsonSerializerRegistry serializerRegistry, LinqProvider linqProvider) + { + throw new InvalidOperationException(); + } } internal sealed class GroupExpressionProjection : ProjectionDefinition @@ -1938,14 +1943,19 @@ public override RenderedProjectionDefinition Render(IBsonSerializer RenderForFind(IBsonSerializer sourceSerializer, IBsonSerializerRegistry serializerRegistry, LinqProvider linqProvider) + { + throw new InvalidOperationException(); + } } - internal sealed class ProjectExpressionProjection : ProjectionDefinition + internal sealed class ExpressionProjectionDefinition : ProjectionDefinition { private readonly Expression> _expression; private readonly ExpressionTranslationOptions _translationOptions; - public ProjectExpressionProjection(Expression> expression, ExpressionTranslationOptions translationOptions) + public ExpressionProjectionDefinition(Expression> expression, ExpressionTranslationOptions translationOptions) { _expression = Ensure.IsNotNull(expression, nameof(expression)); _translationOptions = translationOptions; // can be null @@ -1960,6 +1970,11 @@ public override RenderedProjectionDefinition Render(IBsonSerializer RenderForFind(IBsonSerializer sourceSerializer, IBsonSerializerRegistry serializerRegistry, LinqProvider linqProvider) + { + return linqProvider.GetAdapter().TranslateExpressionToFindProjection(_expression, sourceSerializer, serializerRegistry); + } } internal class SortPipelineStageDefinition : PipelineStageDefinition diff --git a/src/MongoDB.Driver/ProjectionDefinition.cs b/src/MongoDB.Driver/ProjectionDefinition.cs index 4d1c14a88da..7f1431452f1 100644 --- a/src/MongoDB.Driver/ProjectionDefinition.cs +++ b/src/MongoDB.Driver/ProjectionDefinition.cs @@ -147,6 +147,9 @@ public virtual RenderedProjectionDefinition Render(IBsonSerializer< /// A . public abstract RenderedProjectionDefinition Render(IBsonSerializer sourceSerializer, IBsonSerializerRegistry serializerRegistry, LinqProvider linqProvider); + internal virtual RenderedProjectionDefinition RenderForFind(IBsonSerializer sourceSerializer, IBsonSerializerRegistry serializerRegistry, LinqProvider linqProvider) + => Render(sourceSerializer, serializerRegistry, linqProvider); + /// /// Performs an implicit conversion from to . /// diff --git a/src/MongoDB.Driver/ProjectionDefinitionBuilder.cs b/src/MongoDB.Driver/ProjectionDefinitionBuilder.cs index 528116cb272..52b01102815 100644 --- a/src/MongoDB.Driver/ProjectionDefinitionBuilder.cs +++ b/src/MongoDB.Driver/ProjectionDefinitionBuilder.cs @@ -391,7 +391,7 @@ public ProjectionDefinition Exclude(Expression> f /// public ProjectionDefinition Expression(Expression> expression) { - return new FindExpressionProjectionDefinition(expression); + return new ExpressionProjectionDefinition(expression, null); } /// diff --git a/tests/MongoDB.Driver.Tests/FindExpressionProjectionDefinitionTests.cs b/tests/MongoDB.Driver.Tests/FindExpressionProjectionDefinitionTests.cs new file mode 100644 index 00000000000..cfa3172e4dd --- /dev/null +++ b/tests/MongoDB.Driver.Tests/FindExpressionProjectionDefinitionTests.cs @@ -0,0 +1,65 @@ +/* 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; +using System.Linq.Expressions; +using FluentAssertions; +using MongoDB.Bson.Serialization; +using Xunit; + +namespace MongoDB.Driver.Tests +{ + public class FindExpressionProjectionDefinitionTests + { + [Fact] + public void Projection_to_class_should_work() + => AssertProjection( + x => new Projection { A = x.A, X = x.B }, + "{ A : 1, X : '$B', _id : 0 }"); + + [Fact] + public void Projection_to_anonymous_type_should_work() + => AssertProjection( + x => new { x.A, X = x.B }, + "{ A : 1, X : '$B', _id : 0 }"); + + private void AssertProjection( + Expression> expression, + string expectedProjection) + { + var projection = new FindExpressionProjectionDefinition(expression); + + var renderedProjection = projection.Render( + BsonSerializer.LookupSerializer(), + BsonSerializer.SerializerRegistry); + + renderedProjection.Document.Should().BeEquivalentTo(expectedProjection); + } + + private class Document + { + public string A { get; set; } + + public int B { get; set; } + } + + private class Projection + { + public string A { get; set; } + + public int X { get; set; } + } + } +} diff --git a/tests/MongoDB.Driver.Tests/IFindFluentExtensionsTests.cs b/tests/MongoDB.Driver.Tests/IFindFluentExtensionsTests.cs index afdbd877a87..d9e8448fbf8 100644 --- a/tests/MongoDB.Driver.Tests/IFindFluentExtensionsTests.cs +++ b/tests/MongoDB.Driver.Tests/IFindFluentExtensionsTests.cs @@ -453,7 +453,7 @@ public void SortByDescending_ThenByDescending_should_generate_the_correct_sort() private static void AssertProjection(IFindFluent subject, BsonDocument expectedProjection, LinqProvider linqProvider = LinqProvider.V3) { - Assert.Equal(expectedProjection, subject.Options.Projection.Render(BsonSerializer.SerializerRegistry.GetSerializer(), BsonSerializer.SerializerRegistry, linqProvider).Document); + Assert.Equal(expectedProjection, subject.Options.Projection.RenderForFind(BsonSerializer.SerializerRegistry.GetSerializer(), BsonSerializer.SerializerRegistry, linqProvider).Document); } private static void AssertSort(IFindFluent subject, BsonDocument expectedSort) diff --git a/tests/MongoDB.Driver.Tests/Linq/Linq2ImplementationTestsOnLinq3/MongoQueryableTests.cs b/tests/MongoDB.Driver.Tests/Linq/Linq2ImplementationTestsOnLinq3/MongoQueryableTests.cs index ce946924695..764ed57c22b 100644 --- a/tests/MongoDB.Driver.Tests/Linq/Linq2ImplementationTestsOnLinq3/MongoQueryableTests.cs +++ b/tests/MongoDB.Driver.Tests/Linq/Linq2ImplementationTestsOnLinq3/MongoQueryableTests.cs @@ -215,9 +215,9 @@ public void Distinct_document_preceded_by_select_where() Assert(query, 1, - "{ $project: { 'A': 1, 'B': 1, '_id': 0 } }", - "{ $match: { 'A': 'Awesome' } }", - "{ $group: { '_id': '$$ROOT' } }", + "{ $project: { 'A' : '$A', 'B' : '$B', '_id': 0 } }", + "{ $match: { 'A' : 'Awesome' } }", + "{ $group: { '_id' : '$$ROOT' } }", "{ $replaceRoot : { newRoot : '$_id' } }"); } @@ -233,7 +233,7 @@ public void Distinct_document_preceded_by_where_select() Assert(query, 1, "{ $match : { 'A' : 'Awesome' } }", - "{ $project : { A : 1, B : 1, _id : 0 } }", + "{ $project : { A : '$A', B : '$B', _id : 0 } }", "{ $group : { '_id' : '$$ROOT' } }", "{ $replaceRoot : { newRoot : '$_id' } }"); } @@ -999,7 +999,7 @@ public void Select_new_of_same() Assert(query, 2, - "{ $project : { _id : 1, A : 1 } }"); + "{ $project : { _id : '$_id', A : '$A' } }"); } [Fact] diff --git a/tests/MongoDB.Driver.Tests/Linq/Linq2ImplementationTestsOnLinq3/Translators/AggregateGroupTranslatorTests.cs b/tests/MongoDB.Driver.Tests/Linq/Linq2ImplementationTestsOnLinq3/Translators/AggregateGroupTranslatorTests.cs index c41af2285cf..891be65801b 100644 --- a/tests/MongoDB.Driver.Tests/Linq/Linq2ImplementationTestsOnLinq3/Translators/AggregateGroupTranslatorTests.cs +++ b/tests/MongoDB.Driver.Tests/Linq/Linq2ImplementationTestsOnLinq3/Translators/AggregateGroupTranslatorTests.cs @@ -70,7 +70,7 @@ public void Should_translate_just_id() AssertStages( result.Stages, "{ $group : { _id : '$A' } }", - "{ $project : { _id : 1 } }"); + "{ $project : { _id : '$_id' } }"); result.Value._id.Should().Be("Amazing"); } diff --git a/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Jira/CSharp1555Tests.cs b/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Jira/CSharp1555Tests.cs index 8a80df02da9..cccd471b3c0 100644 --- a/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Jira/CSharp1555Tests.cs +++ b/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Jira/CSharp1555Tests.cs @@ -43,7 +43,7 @@ public void Select_new_Person_should_work() .Select(p => new Person { Id = p.Id, Name = p.Name }); var stages = Translate(collection, queryable); - AssertStages(stages, "{ $project : { _id : 1, Name : 1 } }"); + AssertStages(stages, "{ $project : { _id : '$_id', Name : '$Name' } }"); var result = queryable.ToList().Single(); result.ShouldBeEquivalentTo(new Person { Id = 1, Name = "A" }); @@ -57,7 +57,7 @@ public void Select_new_Person_without_Name_should_work() .Select(p => new Person { Id = p.Id }); var stages = Translate(collection, queryable); - AssertStages(stages, "{ $project : { _id : 1 } }"); + AssertStages(stages, "{ $project : { _id : '$_id' } }"); var result = queryable.ToList().Single(); result.ShouldBeEquivalentTo(new Person { Id = 1, Name = null }); @@ -71,7 +71,7 @@ public void Select_new_Person_without_Id_should_work() .Select(p => new Person { Name = p.Name }); var stages = Translate(collection, queryable); - AssertStages(stages, "{ $project : { Name : 1, _id : 0 } }"); + AssertStages(stages, "{ $project : { Name : '$Name', _id : 0 } }"); var result = queryable.ToList().Single(); result.ShouldBeEquivalentTo(new Person { Id = 0, Name = "A" }); diff --git a/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Jira/CSharp2723Tests.cs b/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Jira/CSharp2723Tests.cs index 05384857dad..8b309b9da70 100644 --- a/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Jira/CSharp2723Tests.cs +++ b/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Jira/CSharp2723Tests.cs @@ -115,7 +115,7 @@ public void Nested_Select_should_work() }", @"{ '$project':{ - '_id':1, + '_id':'$_id', 'ParentName':'$Name', 'Children':{ '$map':{ diff --git a/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Jira/CSharp3614Tests.cs b/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Jira/CSharp3614Tests.cs index c441ef86738..096ebdf248a 100644 --- a/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Jira/CSharp3614Tests.cs +++ b/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Jira/CSharp3614Tests.cs @@ -42,7 +42,7 @@ public void Test() }); var stages = Translate(collection, queryable); - AssertStages(stages, "{ $project : { _id : 1, PageCount : 1, Author : { $cond : { if : { $eq : ['$Author', null] }, then : null, else : { _id : '$Author._id', Name : '$Author.Name' } } } } }"); + AssertStages(stages, "{ $project : { _id : '$_id', PageCount : '$PageCount', Author : { $cond : { if : { $eq : ['$Author', null] }, then : null, else : { _id : '$Author._id', Name : '$Author.Name' } } } } }"); var results = queryable.ToList().OrderBy(r => r.Id).ToList(); results.Should().HaveCount(2); diff --git a/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Jira/CSharp3922Tests.cs b/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Jira/CSharp3922Tests.cs index ced22bbbe88..aefc34c039c 100644 --- a/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Jira/CSharp3922Tests.cs +++ b/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Jira/CSharp3922Tests.cs @@ -49,7 +49,7 @@ public void Select_with_constructor_call_should_work() var stages = Translate(collection, queryable); AssertStages( stages, - "{ $project : { X : 1, _id : 0 } }", + "{ $project : { X : '$X', _id : 0 } }", "{ $project : { R : '$X', S : '$Y', _id : 0 } }", "{ $project : { T : '$R', U : '$S', _id : 0 } }"); } @@ -67,7 +67,7 @@ public void Select_with_constructor_call_and_property_set_should_work() var stages = Translate(collection, queryable); AssertStages( stages, - "{ $project : { X : 1, Y : { $literal : 123 }, _id : 0 } }", + "{ $project : { X : '$X', Y : { $literal : 123 }, _id : 0 } }", "{ $project : { R : '$X', S : '$Y', _id : 0 } }", "{ $project : { T : '$R', U : '$S', _id : 0 } }"); } diff --git a/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Jira/CSharp4468Tests.cs b/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Jira/CSharp4468Tests.cs index e5bd5b568fa..330e9c44801 100644 --- a/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Jira/CSharp4468Tests.cs +++ b/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Jira/CSharp4468Tests.cs @@ -59,7 +59,7 @@ public void Query1_should_should_work( "{ $project : { _v : '$Lines', _id : 0 } }", "{ $unwind : '$_v' }", "{ $group : { _id : '$_v.ItemId', __agg0 : { $sum : '$_v.TotalAmount' } } }", - "{ $project : { _id : 1, TotalAmount : '$__agg0' } }" + "{ $project : { _id : '$_id', TotalAmount : '$__agg0' } }" }; } AssertStages(stages, expectedStages); @@ -96,7 +96,7 @@ public void Query2_should_should_work( expectedStages = new[] { "{ $group : { _id : '$_id', __agg0 : { $sum : '$TotalAmount' } } }", - "{ $project : { _id : 1, TotalAmount : '$__agg0' } }" // only difference from LINQ2 is "_id" vs "Id" + "{ $project : { _id : '$_id', TotalAmount : '$__agg0' } }" // only difference from LINQ2 is "_id" vs "Id" }; } AssertStages(stages, expectedStages); diff --git a/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Jira/CSharp4524Tests.cs b/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Jira/CSharp4524Tests.cs index c0814d2ddcd..07113f2cc20 100644 --- a/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Jira/CSharp4524Tests.cs +++ b/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Jira/CSharp4524Tests.cs @@ -33,10 +33,9 @@ public void Find_with_projection_using_LINQ2_should_work() var results = find.ToList(); var projection = find.Options.Projection; - var serializerRegistry = BsonSerializer.SerializerRegistry; - var documentSerializer = serializerRegistry.GetSerializer(); - var renderedProjection = projection.Render(documentSerializer, serializerRegistry, LinqProvider.V2); - renderedProjection.Document.Should().Be("{ SpawnPeriod : 1, StartDate : 1, _id : 0 }"); + + var renderedProjection = TranslateFindProjection(collection, projection, LinqProvider.V2); + renderedProjection.Should().Be("{ SpawnPeriod : 1, StartDate : 1, _id : 0 }"); results.Should().HaveCount(1); results[0].Date.Should().Be(new DateTime(2023, 1, 2, 3, 4, 5, DateTimeKind.Utc)); diff --git a/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Jira/CSharp4651Tests.cs b/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Jira/CSharp4651Tests.cs index ef11fb9aa03..5b017a3a437 100644 --- a/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Jira/CSharp4651Tests.cs +++ b/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Jira/CSharp4651Tests.cs @@ -49,7 +49,7 @@ public void First_custom_projection_should_work( AssertStages( stages, "{ $match : { VehicleType : 0 } }", - "{ $project : { _id : 1, Description : 1 } }"); + "{ $project : { _id : '$_id', Description : '$Description' } }"); } var results = queryable.ToList(); @@ -82,7 +82,7 @@ public void Second_custom_projection_should_work( AssertStages( stages, "{ $match : { VehicleType : 1 } }", - "{ $project : { _id : 1, Description : 'No description available for trucks' } }"); + "{ $project : { _id : '$_id', Description : 'No description available for trucks' } }"); } var results = queryable.ToList(); diff --git a/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Linq3IntegrationTest.cs b/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Linq3IntegrationTest.cs index 05ab5471ba6..b2539286f6a 100644 --- a/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Linq3IntegrationTest.cs +++ b/tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Linq3IntegrationTest.cs @@ -187,11 +187,18 @@ protected BsonDocument TranslateFindProjection( IFindFluent find, LinqProvider linqProvider) { - var findOptions = ((FindFluent)find).Options; - var projection = findOptions.Projection; + var projection = ((FindFluent)find).Options.Projection; + return TranslateFindProjection(collection, projection, linqProvider); + } + + protected BsonDocument TranslateFindProjection( + IMongoCollection collection, + ProjectionDefinition projection, + LinqProvider linqProvider) + { var documentSerializer = collection.DocumentSerializer; var serializerRegistry = BsonSerializer.SerializerRegistry; - var renderedProjection = projection.Render(documentSerializer, serializerRegistry, linqProvider); + var renderedProjection = projection.RenderForFind(documentSerializer, serializerRegistry, linqProvider); return renderedProjection.Document; } } diff --git a/tests/MongoDB.Driver.Tests/Samples/AggregationSample.cs b/tests/MongoDB.Driver.Tests/Samples/AggregationSample.cs index 438398a4b5f..bd732baf0f2 100644 --- a/tests/MongoDB.Driver.Tests/Samples/AggregationSample.cs +++ b/tests/MongoDB.Driver.Tests/Samples/AggregationSample.cs @@ -214,7 +214,7 @@ public async Task Largest_and_smallest_cities_by_state( "{ \"$sort\" : { \"Population\" : 1 } }, " + "{ \"$group\" : { \"_id\" : \"$StateAndCity.State\", \"__agg0\" : { \"$last\" : \"$$ROOT\" }, \"__agg1\" : { \"$first\" : \"$$ROOT\" } } }, " + "{ \"$project\" : { \"State\" : \"$_id\", \"BiggestCity\" : \"$__agg0.StateAndCity.City\", \"BiggestPopulation\" : \"$__agg0.Population\", \"SmallestCity\" : \"$__agg1.StateAndCity.City\", \"SmallestPopulation\" : \"$__agg1.Population\", \"_id\" : 0 } }, " + - "{ \"$project\" : { \"State\" : 1, \"BiggestCity\" : { \"Name\" : \"$BiggestCity\", \"Population\" : \"$BiggestPopulation\" }, \"SmallestCity\" : { \"Name\" : \"$SmallestCity\", \"Population\" : \"$SmallestPopulation\" }, \"_id\" : 0 } }, " + + "{ \"$project\" : { \"State\" : \"$State\", \"BiggestCity\" : { \"Name\" : \"$BiggestCity\", \"Population\" : \"$BiggestPopulation\" }, \"SmallestCity\" : { \"Name\" : \"$SmallestCity\", \"Population\" : \"$SmallestPopulation\" }, \"_id\" : 0 } }, " + "{ \"$sort\" : { \"State\" : 1 } }])"; pipelineTranslation.Should().Be(expectedTranslation);