// public static methods public static ExecutableQuery <TDocument, int> Translate <TDocument>(MongoQueryProvider <TDocument> provider, TranslationContext context, MethodCallExpression expression) { var method = expression.Method; var arguments = expression.Arguments; if (method.IsOneOf(__countMethods)) { var sourceExpression = arguments[0]; var pipeline = ExpressionToPipelineTranslator.Translate(context, sourceExpression); if (method.IsOneOf(__countWithPredicateMethods)) { var predicateLambda = ExpressionHelper.UnquoteLambda(arguments[1]); var predicateFilter = ExpressionToFilterTranslator.TranslateLambda(context, predicateLambda, parameterSerializer: pipeline.OutputSerializer); pipeline = pipeline.AddStages( pipeline.OutputSerializer, AstStage.Match(predicateFilter)); } pipeline = pipeline.AddStages( __wrappedInt32Serializer, AstStage.Count("_v")); 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.Is(QueryableMethod.ElementAt)) { var sourceExpression = arguments[0]; var pipeline = ExpressionToPipelineTranslator.Translate(context, sourceExpression); var indexExpression = arguments[1]; var indexValue = indexExpression.GetConstantValue <int>(containingExpression: expression); pipeline = pipeline.AddStages( pipeline.OutputSerializer, AstStage.Skip(indexValue), AstStage.Limit(1)); return(ExecutableQuery.Create( provider.Collection, provider.Options, pipeline, __finalizer)); } throw new ExpressionNotSupportedException(expression); }
// public static methods public static ExecutableQuery <TDocument, bool> Translate <TDocument>(MongoQueryProvider <TDocument> provider, TranslationContext context, MethodCallExpression expression) { var method = expression.Method; var arguments = expression.Arguments; if (method.Is(QueryableMethod.All)) { var sourceExpression = arguments[0]; var pipeline = ExpressionToPipelineTranslator.Translate(context, sourceExpression); var predicateLambda = ExpressionHelper.UnquoteLambda(arguments[1]); var predicateFilter = ExpressionToFilterTranslator.TranslateLambda(context, predicateLambda, parameterSerializer: pipeline.OutputSerializer); pipeline = pipeline.AddStages( __outputSerializer, AstStage.Match(AstFilter.Not(predicateFilter)), AstStage.Limit(1), AstStage.Project( AstProject.ExcludeId(), AstProject.Set("_v", BsonNull.Value))); 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(__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, IAsyncCursor <TOutput> > Translate <TDocument, TOutput>(MongoQueryProvider <TDocument> provider, Expression expression) { expression = PartialEvaluator.EvaluatePartially(expression); var context = TranslationContext.Create(expression, provider.CollectionDocumentSerializer); var pipeline = ExpressionToPipelineTranslator.Translate(context, expression); return(ExecutableQuery.Create( provider.Collection, provider.Options, pipeline, IdentityFinalizer <TOutput> .Instance)); }
// 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(__maxMethods)) { var sourceExpression = arguments[0]; var pipeline = ExpressionToPipelineTranslator.Translate(context, sourceExpression); var sourceSerializer = pipeline.OutputSerializer; var root = AstExpression.Var("ROOT", isCurrent: true); AstExpression valueAst; IBsonSerializer valueSerializer; if (method.IsOneOf(__maxWithSelectorMethods)) { var selectorLambda = ExpressionHelper.UnquoteLambda(arguments[1]); var selectorTranslation = ExpressionToAggregationExpressionTranslator.TranslateLambdaBody(context, selectorLambda, sourceSerializer, asRoot: true); if (selectorTranslation.Serializer is IBsonDocumentSerializer) { valueAst = selectorTranslation.Ast; valueSerializer = selectorTranslation.Serializer; } else { valueAst = AstExpression.ComputedDocument(new[] { AstExpression.ComputedField("_v", selectorTranslation.Ast) }); valueSerializer = WrappedValueSerializer.Create("_v", selectorTranslation.Serializer); } } else { valueAst = root; valueSerializer = pipeline.OutputSerializer; } pipeline = pipeline.AddStages( valueSerializer, AstStage.Group( id: BsonNull.Value, fields: AstExpression.AccumulatorField("_max", AstAccumulatorOperator.Max, valueAst)), AstStage.ReplaceRoot(AstExpression.GetField(root, "_max"))); return(ExecutableQuery.Create( provider.Collection, provider.Options, pipeline, __finalizer)); } throw new ExpressionNotSupportedException(expression); }
// public static methods public static ExecutableQuery <TDocument, bool> Translate <TDocument>(MongoQueryProvider <TDocument> provider, TranslationContext context, MethodCallExpression expression) { var method = expression.Method; var arguments = expression.Arguments; if (method.Is(QueryableMethod.Contains)) { var sourceExpression = arguments[0]; var pipeline = ExpressionToPipelineTranslator.Translate(context, sourceExpression); IBsonSerializer valueSerializer; if (pipeline.OutputSerializer is IWrappedValueSerializer wrappedValueSerializer) { valueSerializer = wrappedValueSerializer.ValueSerializer; } else { valueSerializer = pipeline.OutputSerializer; wrappedValueSerializer = WrappedValueSerializer.Create("_v", valueSerializer); pipeline = pipeline.AddStages( wrappedValueSerializer, AstStage.Project( AstProject.ExcludeId(), AstProject.Set("_v", AstExpression.Var("ROOT")))); } var itemExpression = arguments[1]; var itemValue = itemExpression.GetConstantValue <object>(containingExpression: expression); var serializedValue = SerializationHelper.SerializeValue(pipeline.OutputSerializer, itemValue); AstFilter filter = AstFilter.Eq(AstFilter.Field("_v", valueSerializer), serializedValue); pipeline = pipeline.AddStages( __outputSerializer, AstStage.Match(filter), AstStage.Limit(1), AstStage.Project( AstProject.ExcludeId(), AstProject.Set("_v", BsonNull.Value))); 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); }
// public 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(__lastMethods)) { var sourceExpression = arguments[0]; var pipeline = ExpressionToPipelineTranslator.Translate(context, sourceExpression); if (method.IsOneOf(__lastWithPredicateMethods)) { var predicateLambda = ExpressionHelper.UnquoteLambda(arguments[1]); var predicateFilter = ExpressionToFilterTranslator.TranslateLambda(context, predicateLambda, parameterSerializer: pipeline.OutputSerializer); pipeline = pipeline.AddStages( pipeline.OutputSerializer, AstStage.Match(predicateFilter)); } pipeline = pipeline.AddStages( pipeline.OutputSerializer, AstStage.Group( id: BsonNull.Value, fields: AstExpression.AccumulatorField("_last", AstAccumulatorOperator.Last, AstExpression.Var("ROOT")))); var finalizer = method.Name == "LastOrDefault" ? __singleOrDefaultFinalizer : __singleFinalizer; return(ExecutableQuery.Create( provider.Collection, provider.Options, pipeline, finalizer)); } throw new ExpressionNotSupportedException(expression); }