// public static methods public static ExecutableQuery <TDocument, TOutput> Translate <TDocument>(MongoQueryProvider <TDocument> provider, TranslationContext context, MethodCallExpression expression) { var method = expression.Method; var arguments = expression.Arguments; if (method.IsOneOf(__averageMethods)) { var sourceExpression = arguments[0]; var pipeline = ExpressionToPipelineTranslator.Translate(context, sourceExpression); var sourceSerializer = pipeline.OutputSerializer; AstExpression valueExpression; if (method.IsOneOf(__averageWithSelectorMethods)) { var selectorLambda = ExpressionHelper.UnquoteLambda(arguments[1]); var selectorTranslation = ExpressionToAggregationExpressionTranslator.TranslateLambdaBody(context, selectorLambda, sourceSerializer, asRoot: true); valueExpression = selectorTranslation.Ast; } else { Ensure.That(sourceSerializer is IWrappedValueSerializer, "Expected sourceSerializer to be an IWrappedValueSerializer.", nameof(sourceSerializer)); var root = AstExpression.Var("ROOT", isCurrent: true); valueExpression = AstExpression.GetField(root, "_v"); } IBsonSerializer outputValueSerializer = expression.GetResultType() switch { Type t when t == typeof(int) => new Int32Serializer(), Type t when t == typeof(long) => new Int64Serializer(), Type t when t == typeof(float) => new SingleSerializer(), Type t when t == typeof(double) => new DoubleSerializer(), Type t when t == typeof(decimal) => new DecimalSerializer(), Type { IsConstructedGenericType : true } t when t.GetGenericTypeDefinition() == typeof(Nullable <>) => (IBsonSerializer)Activator.CreateInstance(typeof(NullableSerializer <>).MakeGenericType(t.GenericTypeArguments[0])), _ => throw new ExpressionNotSupportedException(expression) }; var outputWrappedValueSerializer = WrappedValueSerializer.Create("_v", outputValueSerializer); pipeline = pipeline.AddStages( outputWrappedValueSerializer, AstStage.Group( id: BsonNull.Value, fields: AstExpression.AccumulatorField("_v", AstAccumulatorOperator.Avg, valueExpression)), AstStage.Project(AstProject.ExcludeId())); return(ExecutableQuery.Create( provider.Collection, provider.Options, pipeline, __finalizer)); } throw new ExpressionNotSupportedException(expression); } }
// public static methods public static ExecutableQuery <TDocument, TOutput> Translate <TDocument>(MongoQueryProvider <TDocument> provider, TranslationContext context, MethodCallExpression expression) { var method = expression.Method; var arguments = expression.Arguments; if (method.IsOneOf(__standardDeviationMethods)) { var sourceExpression = ConvertHelper.RemoveConvertToMongoQueryable(arguments[0]); var pipeline = ExpressionToPipelineTranslator.Translate(context, sourceExpression); var sourceSerializer = pipeline.OutputSerializer; var stdDevOperator = method.IsOneOf(__standardDeviationPopulationMethods) ? AstAccumulatorOperator.StdDevPop : AstAccumulatorOperator.StdDevSamp; AstExpression valueAst; if (method.IsOneOf(__standardDeviationWithSelectorMethods)) { var selectorLambda = ExpressionHelper.UnquoteLambda(arguments[1]); var selectorTranslation = ExpressionToAggregationExpressionTranslator.TranslateLambdaBody(context, selectorLambda, sourceSerializer, asRoot: true); valueAst = selectorTranslation.Ast; } else { var root = AstExpression.Var("ROOT", isCurrent: true); valueAst = AstExpression.GetField(root, "_v"); } var outputValueType = expression.GetResultType(); var outputValueSerializer = BsonSerializer.LookupSerializer(outputValueType); var outputWrappedValueSerializer = WrappedValueSerializer.Create("_v", outputValueSerializer); pipeline = pipeline.AddStages( outputWrappedValueSerializer, AstStage.Group( id: BsonNull.Value, AstExpression.AccumulatorField("_v", stdDevOperator, valueAst)), AstStage.Project(AstProject.ExcludeId())); var finalizer = method.IsOneOf(__standardDeviationNullableMethods) ? __singleOrDefaultFinalizer : __singleFinalizer; return(ExecutableQuery.Create( provider.Collection, provider.Options, pipeline, finalizer)); } throw new ExpressionNotSupportedException(expression); }
// public static methods public static ExecutableQuery <TDocument, TOutput> Translate <TDocument>(MongoQueryProvider <TDocument> provider, TranslationContext context, MethodCallExpression expression) { var method = expression.Method; var arguments = expression.Arguments; if (method.IsOneOf(__sumMethods)) { var sourceExpression = arguments[0]; var pipeline = ExpressionToPipelineTranslator.Translate(context, sourceExpression); var sourceSerializer = pipeline.OutputSerializer; AstExpression valueAst; if (method.IsOneOf(__sumWithSelectorMethods)) { var selectorLambda = ExpressionHelper.UnquoteLambda(arguments[1]); var selectorTranslation = ExpressionToAggregationExpressionTranslator.TranslateLambdaBody(context, selectorLambda, sourceSerializer, asRoot: true); valueAst = selectorTranslation.Ast; } else { Ensure.That(sourceSerializer is IWrappedValueSerializer, "Expected sourceSerializer to be an IWrappedValueSerializer.", nameof(sourceSerializer)); var rootVar = AstExpression.Var("ROOT", isCurrent: true); valueAst = AstExpression.GetField(rootVar, "_v"); } var outputValueType = expression.GetResultType(); var outputValueSerializer = BsonSerializer.LookupSerializer(outputValueType); var outputWrappedValueSerializer = WrappedValueSerializer.Create("_v", outputValueSerializer); pipeline = pipeline.AddStages( outputWrappedValueSerializer, AstStage.Group( id: BsonNull.Value, fields: AstExpression.AccumulatorField("_v", AstAccumulatorOperator.Sum, valueAst)), AstStage.Project(AstProject.ExcludeId())); return(ExecutableQuery.Create( provider.Collection, provider.Options, pipeline, __finalizer)); } throw new ExpressionNotSupportedException(expression); }