// public static methods public static AstPipeline Translate(TranslationContext context, MethodCallExpression expression) { var method = expression.Method; var arguments = expression.Arguments; if (method.Is(QueryableMethod.Select)) { var sourceExpression = arguments[0]; var pipeline = ExpressionToPipelineTranslator.Translate(context, sourceExpression); var sourceSerializer = pipeline.OutputSerializer; var selectorLambda = ExpressionHelper.UnquoteLambda(arguments[1]); if (selectorLambda.Body == selectorLambda.Parameters[0]) { return(pipeline); // ignore identity projection: Select(x => x) } var selectorTranslation = ExpressionToAggregationExpressionTranslator.TranslateLambdaBody(context, selectorLambda, sourceSerializer, asRoot: true); var(projectStage, projectionSerializer) = ProjectionHelper.CreateProjectStage(selectorTranslation); pipeline = pipeline.AddStages(projectionSerializer, projectStage); return(pipeline); } throw new ExpressionNotSupportedException(expression); }
// public static methods public static AstPipeline Translate(TranslationContext context, MethodCallExpression expression) { var method = expression.Method; var arguments = expression.Arguments; if (method.Is(QueryableMethod.Join)) { var outerExpression = arguments[0]; var pipeline = ExpressionToPipelineTranslator.Translate(context, outerExpression); var outerSerializer = pipeline.OutputSerializer; var wrapOuterStage = AstStage.Project( AstProject.Set("_outer", AstExpression.Var("ROOT")), AstProject.ExcludeId()); var wrappedOuterSerializer = WrappedValueSerializer.Create("_outer", outerSerializer); var innerExpression = arguments[1]; var(innerCollectionName, innerSerializer) = innerExpression.GetCollectionInfo(containerExpression: expression); var outerKeySelectorLambda = ExpressionHelper.UnquoteLambda(arguments[2]); var localFieldPath = outerKeySelectorLambda.GetFieldPath(context, wrappedOuterSerializer); var innerKeySelectorLambda = ExpressionHelper.UnquoteLambda(arguments[3]); var foreignFieldPath = innerKeySelectorLambda.GetFieldPath(context, innerSerializer); var lookupStage = AstStage.Lookup( from: innerCollectionName, match: new AstLookupStageEqualityMatch(localFieldPath, foreignFieldPath), @as: "_inner"); var unwindStage = AstStage.Unwind("_inner"); var resultSelectorLambda = ExpressionHelper.UnquoteLambda(arguments[4]); var root = AstExpression.Var("ROOT", isCurrent: true); var outerParameter = resultSelectorLambda.Parameters[0]; var outerField = AstExpression.GetField(root, "_outer"); var outerSymbol = context.CreateSymbol(outerParameter, outerField, outerSerializer); var innerParameter = resultSelectorLambda.Parameters[1]; var innerField = AstExpression.GetField(root, "_inner"); var innerSymbol = context.CreateSymbol(innerParameter, innerField, innerSerializer); var resultSelectorContext = context.WithSymbols(outerSymbol, innerSymbol); var resultSelectorTranslation = ExpressionToAggregationExpressionTranslator.Translate(resultSelectorContext, resultSelectorLambda.Body); var(projectStage, newOutputSerializer) = ProjectionHelper.CreateProjectStage(resultSelectorTranslation); pipeline = pipeline.AddStages( newOutputSerializer, wrapOuterStage, lookupStage, unwindStage, projectStage); return(pipeline); } throw new ExpressionNotSupportedException(expression); }
private static AstPipeline TranslateResultSelector( TranslationContext context, AstPipeline pipeline, ReadOnlyCollection <Expression> arguments, IBsonSerializer keySerializer, IBsonSerializer elementSerializer) { var resultSelectorLambda = ExpressionHelper.UnquoteLambda(arguments.Last()); var root = AstExpression.Var("ROOT", isCurrent: true); var keyParameter = resultSelectorLambda.Parameters[0]; var keyField = AstExpression.GetField(root, "_id"); var keySymbol = context.CreateSymbol(keyParameter, keyField, keySerializer); var elementsParameter = resultSelectorLambda.Parameters[1]; var elementsField = AstExpression.GetField(root, "_elements"); var elementsSerializer = IEnumerableSerializer.Create(elementSerializer); var elementsSymbol = context.CreateSymbol(elementsParameter, elementsField, elementsSerializer); var resultSelectContext = context.WithSymbols(keySymbol, elementsSymbol); var resultSelectorTranslation = ExpressionToAggregationExpressionTranslator.Translate(resultSelectContext, resultSelectorLambda.Body); var(projectStage, projectionSerializer) = ProjectionHelper.CreateProjectStage(resultSelectorTranslation); return(pipeline.AddStages(projectionSerializer, projectStage)); }