/// <summary> /// Modifies the given query model for fetching, adding an <see cref="AdditionalFromClause"/> and changing the <see cref="SelectClause.Selector"/> to /// retrieve the result of the <see cref="AdditionalFromClause"/>. /// For example, a fetch request such as <c>FetchMany (x => x.Orders)</c> will be transformed into a <see cref="AdditionalFromClause"/> selecting /// <c>y.Orders</c> (where <c>y</c> is what the query model originally selected) and a <see cref="SelectClause"/> selecting the result of the /// <see cref="AdditionalFromClause"/>. /// This method is called by <see cref="FetchRequestBase.CreateFetchQueryModel"/> in the process of creating the new fetch query model. /// </summary> protected override void ModifyFetchQueryModel (QueryModel fetchQueryModel) { ArgumentUtility.CheckNotNull ("fetchQueryModel", fetchQueryModel); var fromExpression = GetFetchedMemberExpression (new QuerySourceReferenceExpression (fetchQueryModel.MainFromClause)); var memberFromClause = new AdditionalFromClause (fetchQueryModel.GetNewName ("#fetch"), _relatedObjectType, fromExpression); fetchQueryModel.BodyClauses.Add (memberFromClause); var newSelector = new QuerySourceReferenceExpression (memberFromClause); var newSelectClause = new SelectClause (newSelector); fetchQueryModel.SelectClause = newSelectClause; }
/// <summary> /// Replaces the given parameter with a back-reference to the <see cref="IQuerySource"/> corresponding to <paramref name="referencedNode"/>. /// </summary> /// <param name="referencedNode">The referenced node.</param> /// <param name="parameterToReplace">The parameter to replace with a <see cref="QuerySourceReferenceExpression"/>.</param> /// <param name="expression">The expression in which to replace the parameter.</param> /// <param name="context">The clause generation context.</param> /// <returns><paramref name="expression"/>, with <paramref name="parameterToReplace"/> replaced with a <see cref="QuerySourceReferenceExpression"/> /// pointing to the clause corresponding to <paramref name="referencedNode"/>.</returns> public static Expression ReplaceParameterWithReference ( IQuerySourceExpressionNode referencedNode, ParameterExpression parameterToReplace, Expression expression, ClauseGenerationContext context) { ArgumentUtility.CheckNotNull ("referencedNode", referencedNode); ArgumentUtility.CheckNotNull ("parameterToReplace", parameterToReplace); ArgumentUtility.CheckNotNull ("expression", expression); ArgumentUtility.CheckNotNull ("context", context); var clause = GetQuerySourceForNode (referencedNode, context); var referenceExpression = new QuerySourceReferenceExpression (clause); return ReplacingExpressionTreeVisitor.Replace (parameterToReplace, referenceExpression, expression); }
protected override Expression VisitQuerySourceReferenceExpression (QuerySourceReferenceExpression expression) { ArgumentUtility.CheckNotNull ("expression", expression); if (QuerySourceMapping.ContainsMapping (expression.ReferencedQuerySource)) { return QuerySourceMapping.GetExpression (expression.ReferencedQuerySource); } else if (_throwOnUnmappedReferences) { var message = "Cannot replace reference to clause '" + expression.ReferencedQuerySource.ItemName + "', there is no mapped expression."; throw new InvalidOperationException (message); } else { return expression; } }
protected override Expression VisitQuerySourceReferenceExpression (QuerySourceReferenceExpression expression) { ArgumentUtility.CheckNotNull ("expression", expression); return Expression.Parameter (expression.Type, "[" + expression.ReferencedQuerySource.ItemName + "]"); }
protected override Expression VisitQuerySourceReferenceExpression (QuerySourceReferenceExpression expression) { ArgumentUtility.CheckNotNull ("expression", expression); try { var accessorLambda = AccessorFindingExpressionTreeVisitor.FindAccessorLambda (expression, _itemExpression, _lambdaParameter); return accessorLambda.Body; } catch (ArgumentException ex) { var message = string.Format ( "Cannot create a LambdaExpression that retrieves the value of '{0}' from items with a structure of '{1}'. The item expression does not " + "contain the value or it is too complex.", FormattingExpressionTreeVisitor.Format (expression), FormattingExpressionTreeVisitor.Format (_itemExpression)); throw new InvalidOperationException (message, ex); } }