Skip to content

Commit d45424e

Browse files
committed
CSHARP-5748: Use KeyValuePairSerializer consistently for KeyValuePair
1 parent 16ad04f commit d45424e

File tree

4 files changed

+35
-30
lines changed

4 files changed

+35
-30
lines changed

src/MongoDB.Bson/Serialization/Serializers/KeyValuePairSerializer.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,30 @@ public interface IKeyValuePairSerializer
2929
BsonType Representation { get; }
3030
}
3131

32+
/// <summary>
33+
/// Static factory class for KeyValuePairSerializers.
34+
/// </summary>
35+
public static class KeyValuePairSerializer
36+
{
37+
/// <summary>
38+
/// Creates a KeyValuePairSerializer.
39+
/// </summary>
40+
/// <param name="representation">The representation.</param>
41+
/// <param name="keySerializer">The key serializer.</param>
42+
/// <param name="valueSerializer">The value Serializer.</param>
43+
/// <returns>A KeyValuePairSerializer.</returns>
44+
public static IBsonSerializer Create(
45+
BsonType representation,
46+
IBsonSerializer keySerializer,
47+
IBsonSerializer valueSerializer)
48+
{
49+
var keyType = keySerializer.ValueType;
50+
var valueType = valueSerializer.ValueType;
51+
var keyValuePairSerializerType = typeof(KeyValuePairSerializer<,>).MakeGenericType(keyType, valueType);
52+
return (IBsonSerializer)Activator.CreateInstance(keyValuePairSerializerType, [representation, keySerializer, valueSerializer]);
53+
}
54+
}
55+
3256
/// <summary>
3357
/// Represents a serializer for KeyValuePairs.
3458
/// </summary>

src/MongoDB.Driver/Linq/Linq3Implementation/Translators/ExpressionToAggregationExpressionTranslators/NewKeyValuePairExpressionToAggregationExpressionTranslator.cs

Lines changed: 8 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
using System;
1717
using System.Collections.Generic;
1818
using System.Linq.Expressions;
19+
using MongoDB.Bson;
1920
using MongoDB.Bson.Serialization;
21+
using MongoDB.Bson.Serialization.Serializers;
2022
using MongoDB.Driver.Linq.Linq3Implementation.Ast.Expressions;
2123

2224
namespace MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToAggregationExpressionTranslators
@@ -43,37 +45,16 @@ public static TranslatedExpression Translate(
4345
var keyTranslation = ExpressionToAggregationExpressionTranslator.Translate(context, keyExpression);
4446
var valueTranslation = ExpressionToAggregationExpressionTranslator.Translate(context, valueExpression);
4547

46-
var serializer = CreateResultSerializer(expression.Type, keyTranslation.Serializer, valueTranslation.Serializer, out var keyElementName, out var valueElementName);
4748
var ast = AstExpression.ComputedDocument([
48-
AstExpression.ComputedField(keyElementName, keyTranslation.Ast),
49-
AstExpression.ComputedField(valueElementName, valueTranslation.Ast)
49+
AstExpression.ComputedField("k", keyTranslation.Ast),
50+
AstExpression.ComputedField("v", valueTranslation.Ast)
5051
]);
5152

52-
return new TranslatedExpression(expression, ast, serializer);
53-
}
54-
55-
private static IBsonSerializer CreateResultSerializer(
56-
Type resultType,
57-
IBsonSerializer keySerializer,
58-
IBsonSerializer valueSerializer,
59-
out string keyElementName,
60-
out string valueElementName)
61-
{
62-
var constructorInfo = resultType.GetConstructor([keySerializer.ValueType, valueSerializer.ValueType]);
63-
var classMap = new BsonClassMap(resultType);
64-
classMap.MapConstructor(constructorInfo);
65-
classMap.AutoMap();
66-
var keyMemberMap = classMap.GetMemberMap("Key");
67-
keyElementName = keyMemberMap.ElementName;
68-
keyMemberMap.SetSerializer(keySerializer);
69-
var valueMemberMap = classMap.GetMemberMap("Value");
70-
valueElementName = valueMemberMap.ElementName;
71-
valueMemberMap.SetSerializer(valueSerializer);
72-
classMap.Freeze();
53+
var keySerializer = keyTranslation.Serializer;
54+
var valueSerializer = valueTranslation.Serializer;
55+
var keyValuePairSerializer = KeyValuePairSerializer.Create(BsonType.Document, keySerializer, valueSerializer);
7356

74-
// have to use BsonClassMapSerializer here to mimic the MemberInitExpressionToAggregationExpressionTranslator to avoid risking a behavioral breaking change
75-
var serializerType = typeof(BsonClassMapSerializer<>).MakeGenericType(resultType);
76-
return (IBsonSerializer)Activator.CreateInstance(serializerType, classMap);
57+
return new TranslatedExpression(expression, ast, keyValuePairSerializer);
7758
}
7859
}
7960
}

tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/Jira/CSharp1326Tests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public void Projection_of_ArrayOfDocuments_dictionary_keys_and_values_should_wor
4949
stages,
5050
"{ $match : { ParentId : { $in : [1, 2, 3] }, Gender : 'Male' } }",
5151
"{ $group : { _id : '$ParentId', _elements : { $push : '$$ROOT' } } }",
52-
"{ $project : { Key : '$_id', Value : '$_elements', _id : 0 } }");
52+
"{ $project : { k : '$_id', v : '$_elements', _id : 0 } }");
5353

5454
var results = aggregate.ToList().OrderBy(x => x.Key).ToList();
5555
results[0].Key.Should().Be(1);

tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/Translators/ExpressionToAggregationExpressionTranslators/NewKeyValuePairExpressionToAggregationExpressionTranslatorTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public void NewKeyValuePair_should_translate()
3737
.Select(d => new KeyValuePair<string,int>("X", d.X));
3838

3939
var stages = Translate(collection, queryable);
40-
AssertStages(stages, "{ $project : { Key : 'X', Value : '$X', _id : 0 } }");
40+
AssertStages(stages, "{ $project : { k : 'X', v : '$X', _id : 0 } }");
4141

4242
var result = queryable.Single();
4343
result.Key.Should().Be("X");
@@ -54,7 +54,7 @@ public void KeyValuePair_Create_should_translate()
5454
.Select(d => KeyValuePair.Create("X", d.X));
5555

5656
var stages = Translate(collection, queryable);
57-
AssertStages(stages, "{ $project : { Key : 'X', Value : '$X', _id : 0 } }");
57+
AssertStages(stages, "{ $project : { k : 'X', v : '$X', _id : 0 } }");
5858

5959
var result = queryable.Single();
6060
result.Key.Should().Be("X");

0 commit comments

Comments
 (0)