/// <summary> /// Clones this <see cref="QueryModel"/>, returning a new <see cref="QueryModel"/> equivalent to this instance, but with its clauses being /// clones of this instance's clauses. Any <see cref="QuerySourceReferenceExpression"/> in the cloned clauses that points back to another clause /// in this <see cref="QueryModel"/> (including its subqueries) is adjusted to point to the respective clones in the cloned /// <see cref="QueryModel"/>. Any subquery nested in the <see cref="QueryModel"/> is also cloned. /// </summary> /// <param name="querySourceMapping">The <see cref="QuerySourceMapping"/> defining how to adjust instances of /// <see cref="QuerySourceReferenceExpression"/> in the cloned <see cref="QueryModel"/>. If there is a <see cref="QuerySourceReferenceExpression"/> /// that points out of the <see cref="QueryModel"/> being cloned, specify its replacement via this parameter. At the end of the cloning process, /// this object maps all the clauses in this original <see cref="QueryModel"/> to the clones created in the process. /// </param> public QueryModel Clone(QuerySourceMapping querySourceMapping) { ArgumentUtility.CheckNotNull("querySourceMapping", querySourceMapping); var cloneContext = new CloneContext(querySourceMapping); var queryModelBuilder = new QueryModelBuilder(); queryModelBuilder.AddClause(MainFromClause.Clone(cloneContext)); foreach (var bodyClause in BodyClauses) { queryModelBuilder.AddClause(bodyClause.Clone(cloneContext)); } queryModelBuilder.AddClause(SelectClause.Clone(cloneContext)); foreach (var resultOperator in ResultOperators) { var resultOperatorClone = resultOperator.Clone(cloneContext); queryModelBuilder.AddResultOperator(resultOperatorClone); } var clone = queryModelBuilder.Build(); clone.TransformExpressions(ex => CloningExpressionTreeVisitor.AdjustExpressionAfterCloning(ex, cloneContext.QuerySourceMapping)); clone.ResultTypeOverride = ResultTypeOverride; return(clone); }
public void Replaces_SubQueryExpressions() { var expression = new SubQueryExpression(ExpressionHelper.CreateQueryModel <Cook> ()); var result = CloningExpressionTreeVisitor.AdjustExpressionAfterCloning(expression, _querySourceMapping); Assert.That(((SubQueryExpression)result).QueryModel, Is.Not.SameAs(expression.QueryModel)); }
public void Replaces_SubQueryExpressions_WithCorrectCloneContext() { var subQueryModel = ExpressionHelper.CreateQueryModel <Cook> (); var referencedClause = ExpressionHelper.CreateMainFromClause_Int(); subQueryModel.SelectClause.Selector = new QuerySourceReferenceExpression(referencedClause); var expression = new SubQueryExpression(subQueryModel); var newReferenceExpression = new QuerySourceReferenceExpression(ExpressionHelper.CreateMainFromClause_Int()); _querySourceMapping.AddMapping(referencedClause, newReferenceExpression); var result = CloningExpressionTreeVisitor.AdjustExpressionAfterCloning(expression, _querySourceMapping); var newSubQuerySelectClause = ((SubQueryExpression)result).QueryModel.SelectClause; Assert.That(newSubQuerySelectClause.Selector, Is.SameAs(newReferenceExpression)); }