Skip to content

Commit 89c78f2

Browse files
committed
CSHARP-5572: Implement new KnownSerializerFinder.
1 parent 75200dd commit 89c78f2

File tree

33 files changed

+1985
-197
lines changed

33 files changed

+1985
-197
lines changed

src/MongoDB.Bson/Serialization/IBsonSerializerExtensions.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,38 @@ public static TValue Deserialize<TValue>(this IBsonSerializer<TValue> serializer
5050
return serializer.Deserialize(context, args);
5151
}
5252

53+
/// <summary>
54+
/// Gets the serializer for a base type starting from a serializer for a derived type.
55+
/// </summary>
56+
/// <param name="serializer">The serializer for the derived type.</param>
57+
/// <param name="baseType">The base type.</param>
58+
/// <returns>The serializer for the base type.</returns>
59+
public static IBsonSerializer GetBaseTypeSerializer(this IBsonSerializer serializer, Type baseType)
60+
{
61+
if (!baseType.IsAssignableFrom(serializer.ValueType))
62+
{
63+
throw new ArgumentException($"{baseType} is not assignable from {serializer.ValueType}.");
64+
}
65+
66+
return BsonSerializer.LookupSerializer(baseType); // TODO: should be able to navigate from serializer
67+
}
68+
69+
/// <summary>
70+
/// Gets the serializer for a derived type starting from a serializer for a base type.
71+
/// </summary>
72+
/// <param name="serializer">The serializer for the base type.</param>
73+
/// <param name="derivedType">The derived type.</param>
74+
/// <returns>The serializer for the derived type.</returns>
75+
public static IBsonSerializer GetDerivedTypeSerializer(this IBsonSerializer serializer, Type derivedType)
76+
{
77+
if (!serializer.ValueType.IsAssignableFrom(derivedType))
78+
{
79+
throw new ArgumentException($"{serializer.ValueType} is not assignable from {derivedType}.");
80+
}
81+
82+
return BsonSerializer.LookupSerializer(derivedType); // TODO: should be able to navigate from serializer
83+
}
84+
5385
/// <summary>
5486
/// Gets the discriminator convention for a serializer.
5587
/// </summary>

src/MongoDB.Driver/Linq/Linq3Implementation/ExtensionMethods/ExpressionExtensions.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,17 @@ public static TValue GetConstantValue<TValue>(this Expression expression, Expres
6060
var message = $"Expression must be a constant: {expression} in {containingExpression}.";
6161
throw new ExpressionNotSupportedException(message);
6262
}
63+
64+
public static bool IsConvert(this Expression expression, out Expression operand)
65+
{
66+
if (expression is UnaryExpression unaryExpression && unaryExpression.NodeType == ExpressionType.Convert)
67+
{
68+
operand = unaryExpression.Operand;
69+
return true;
70+
}
71+
72+
operand = null;
73+
return false;
74+
}
6375
}
6476
}

src/MongoDB.Driver/Linq/Linq3Implementation/GroupingWithOutputExpressionStageDefinitions.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ private AstStage RenderProjectStage(
6464
out IBsonSerializer<TOutput> outputSerializer)
6565
{
6666
var partiallyEvaluatedOutput = (Expression<Func<TGrouping, TOutput>>)PartialEvaluator.EvaluatePartially(_output);
67-
var context = TranslationContext.Create(translationOptions);
67+
var parameter = partiallyEvaluatedOutput.Parameters.Single();
68+
var context = TranslationContext.Create(partiallyEvaluatedOutput, initialNode: parameter, initialSerializer: inputSerializer, translationOptions: translationOptions);
6869
var outputTranslation = ExpressionToAggregationExpressionTranslator.TranslateLambdaBody(context, partiallyEvaluatedOutput, inputSerializer, asRoot: true);
6970
var (projectStage, projectSerializer) = ProjectionHelper.CreateProjectStage(outputTranslation);
7071
outputSerializer = (IBsonSerializer<TOutput>)projectSerializer;
@@ -106,7 +107,8 @@ protected override AstStage RenderGroupingStage(
106107
out IBsonSerializer<IGrouping<TValue, TInput>> groupingOutputSerializer)
107108
{
108109
var partiallyEvaluatedGroupBy = (Expression<Func<TInput, TValue>>)PartialEvaluator.EvaluatePartially(_groupBy);
109-
var context = TranslationContext.Create(translationOptions);
110+
var parameter = partiallyEvaluatedGroupBy.Parameters.Single();
111+
var context = TranslationContext.Create(partiallyEvaluatedGroupBy, initialNode: parameter, initialSerializer: inputSerializer, translationOptions: translationOptions);
110112
var groupByTranslation = ExpressionToAggregationExpressionTranslator.TranslateLambdaBody(context, partiallyEvaluatedGroupBy, inputSerializer, asRoot: true);
111113

112114
var valueSerializer = (IBsonSerializer<TValue>)groupByTranslation.Serializer;
@@ -150,7 +152,8 @@ protected override AstStage RenderGroupingStage(
150152
out IBsonSerializer<IGrouping<AggregateBucketAutoResultId<TValue>, TInput>> groupingOutputSerializer)
151153
{
152154
var partiallyEvaluatedGroupBy = (Expression<Func<TInput, TValue>>)PartialEvaluator.EvaluatePartially(_groupBy);
153-
var context = TranslationContext.Create(translationOptions);
155+
var parameter = partiallyEvaluatedGroupBy.Parameters.Single();
156+
var context = TranslationContext.Create(partiallyEvaluatedGroupBy, initialNode: parameter, initialSerializer: inputSerializer, translationOptions: translationOptions);
154157
var groupByTranslation = ExpressionToAggregationExpressionTranslator.TranslateLambdaBody(context, partiallyEvaluatedGroupBy, inputSerializer, asRoot: true);
155158

156159
var valueSerializer = (IBsonSerializer<TValue>)groupByTranslation.Serializer;
@@ -188,7 +191,8 @@ protected override AstStage RenderGroupingStage(
188191
out IBsonSerializer<IGrouping<TValue, TInput>> groupingOutputSerializer)
189192
{
190193
var partiallyEvaluatedGroupBy = (Expression<Func<TInput, TValue>>)PartialEvaluator.EvaluatePartially(_groupBy);
191-
var context = TranslationContext.Create(translationOptions);
194+
var parameter = partiallyEvaluatedGroupBy.Parameters.Single();
195+
var context = TranslationContext.Create(partiallyEvaluatedGroupBy, initialNode: parameter, initialSerializer: inputSerializer, translationOptions: translationOptions);
192196
var groupByTranslation = ExpressionToAggregationExpressionTranslator.TranslateLambdaBody(context, partiallyEvaluatedGroupBy, inputSerializer, asRoot: true);
193197
var pushElements = AstExpression.AccumulatorField("_elements", AstUnaryAccumulatorOperator.Push, AstExpression.RootVar);
194198
var groupBySerializer = (IBsonSerializer<TValue>)groupByTranslation.Serializer;

0 commit comments

Comments
 (0)