SqlDuplicator.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / DLinq / Dlinq / SqlClient / Query / SqlDuplicator.cs / 2 / SqlDuplicator.cs

                            using System; 
using System.Collections.Generic;
using System.Data.Linq;
using System.Data.Linq.Provider;
using System.Diagnostics.CodeAnalysis; 

namespace System.Data.Linq.SqlClient { 
 
    internal class SqlDuplicator {
        DuplicatingVisitor superDuper; 

        internal SqlDuplicator()
            : this(true) {
        } 

        internal SqlDuplicator(bool ignoreExternalRefs) { 
            this.superDuper = new DuplicatingVisitor(ignoreExternalRefs); 
        }
 
        internal static SqlNode Copy(SqlNode node) {
            if (node == null)
                return null;
            switch (node.NodeType) { 
                case SqlNodeType.ColumnRef:
                case SqlNodeType.Value: 
                case SqlNodeType.Parameter: 
                case SqlNodeType.Variable:
                    return node; 
                default:
                    return new SqlDuplicator().Duplicate(node);
            }
        } 

        internal SqlNode Duplicate(SqlNode node) { 
            return this.superDuper.Visit(node); 
        }
 
        [SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Justification="These issues are related to our use of if-then and case statements for node types, which adds to the complexity count however when reviewed they are easy to navigate and understand.")]
        internal class DuplicatingVisitor : SqlVisitor {
            Dictionary nodeMap;
            bool ingoreExternalRefs; 

            internal DuplicatingVisitor(bool ignoreExternalRefs) { 
                this.ingoreExternalRefs = ignoreExternalRefs; 
                this.nodeMap = new Dictionary();
            } 

            internal override SqlNode Visit(SqlNode node) {
                if (node == null) {
                    return null; 
                }
                SqlNode result = null; 
                if (this.nodeMap.TryGetValue(node, out result)) { 
                    return result;
                } 
                result = base.Visit(node);
                this.nodeMap[node] = result;
                return result;
            } 
            internal override SqlExpression VisitDoNotVisit(SqlDoNotVisitExpression expr) {
                // duplicator can duplicate through a do-no-visit node 
                return new SqlDoNotVisitExpression(this.VisitExpression(expr.Expression)); 
            }
            internal override SqlAlias VisitAlias(SqlAlias a) { 
                SqlAlias n = new SqlAlias(a.Node);
                this.nodeMap[a] = n;
                n.Node = this.Visit(a.Node);
                n.Name = a.Name; 
                return n;
            } 
            internal override SqlExpression VisitAliasRef(SqlAliasRef aref) { 
                if (this.ingoreExternalRefs && !this.nodeMap.ContainsKey(aref.Alias)) {
                    return aref; 
                }
                return new SqlAliasRef((SqlAlias)this.Visit(aref.Alias));
            }
            internal override SqlRowNumber VisitRowNumber(SqlRowNumber rowNumber) { 
                List orderBy = new List();
 
                foreach (SqlOrderExpression expr in rowNumber.OrderBy) { 
                    orderBy.Add(new SqlOrderExpression(expr.OrderType, (SqlExpression)this.Visit(expr.Expression)));
                } 

                return new SqlRowNumber(rowNumber.ClrType, rowNumber.SqlType, orderBy, rowNumber.SourceExpression);
            }
            internal override SqlExpression VisitBinaryOperator(SqlBinary bo) { 
                SqlExpression left = (SqlExpression)this.Visit(bo.Left);
                SqlExpression right = (SqlExpression)this.Visit(bo.Right); 
                return new SqlBinary(bo.NodeType, bo.ClrType, bo.SqlType, left, right, bo.Method); 
            }
            internal override SqlExpression VisitCast(SqlUnary c) { 
                SqlExpression op = (SqlExpression)this.Visit(c.Operand);
                return new SqlUnary(SqlNodeType.Cast, c.ClrType, c.SqlType, op, c.SourceExpression);
            }
            internal override SqlExpression VisitClientQuery(SqlClientQuery cq) { 
                SqlSubSelect query = (SqlSubSelect) this.VisitExpression(cq.Query);
                SqlClientQuery nq = new SqlClientQuery(query); 
                for (int i = 0, n = cq.Arguments.Count; i < n; i++) { 
                    nq.Arguments.Add(this.VisitExpression(cq.Arguments[i]));
                } 
                for (int i = 0, n = cq.Parameters.Count; i < n; i++) {
                    nq.Parameters.Add((SqlParameter)this.VisitExpression(cq.Parameters[i]));
                }
                return nq; 
            }
            internal override SqlExpression VisitJoinedCollection(SqlJoinedCollection jc) { 
                return new SqlJoinedCollection(jc.ClrType, jc.SqlType, this.VisitExpression(jc.Expression), this.VisitExpression(jc.Count), jc.SourceExpression); 
            }
            internal override SqlExpression VisitClientArray(SqlClientArray scar) { 
                SqlExpression[] exprs = new SqlExpression[scar.Expressions.Count];
                for (int i = 0, n = exprs.Length; i < n; i++) {
                    exprs[i] = this.VisitExpression(scar.Expressions[i]);
                } 
                return new SqlClientArray(scar.ClrType, scar.SqlType, exprs, scar.SourceExpression);
            } 
            internal override SqlExpression VisitTypeCase(SqlTypeCase tc) { 
                SqlExpression disc = VisitExpression(tc.Discriminator);
                List whens = new List(); 
                foreach(SqlTypeCaseWhen when in tc.Whens) {
                    whens.Add(new SqlTypeCaseWhen(VisitExpression(when.Match), VisitExpression(when.TypeBinding)));
                }
                return new SqlTypeCase(tc.ClrType, tc.SqlType, tc.RowType, disc, whens, tc.SourceExpression); 
            }
            internal override SqlExpression VisitNew(SqlNew sox) { 
                SqlExpression[] args = new SqlExpression[sox.Args.Count]; 
                SqlMemberAssign[] bindings = new SqlMemberAssign[sox.Members.Count];
                for (int i = 0, n = args.Length; i < n; i++) { 
                    args[i] = this.VisitExpression(sox.Args[i]);
                }
                for (int i = 0, n = bindings.Length; i < n; i++) {
                    bindings[i] = this.VisitMemberAssign(sox.Members[i]); 
                }
                return new SqlNew(sox.MetaType, sox.SqlType, sox.Constructor, args, sox.ArgMembers, bindings, sox.SourceExpression); 
            } 
            internal override SqlNode VisitLink(SqlLink link) {
                SqlExpression[] exprs = new SqlExpression[link.KeyExpressions.Count]; 
                for (int i = 0, n = exprs.Length; i < n; i++) {
                    exprs[i] = this.VisitExpression(link.KeyExpressions[i]);
                }
                SqlLink newLink = new SqlLink(new object(), link.RowType, link.ClrType, link.SqlType, null, link.Member, exprs, null, link.SourceExpression); 
                this.nodeMap[link] = newLink;
                // break the potential cyclic tree by visiting these after adding to the map 
                newLink.Expression = this.VisitExpression(link.Expression); 
                newLink.Expansion = this.VisitExpression(link.Expansion);
                return newLink; 
            }
            internal override SqlExpression VisitColumn(SqlColumn col) {
                SqlColumn n = new SqlColumn(col.ClrType, col.SqlType, col.Name, col.MetaMember, null, col.SourceExpression);
                this.nodeMap[col] = n; 
                n.Expression = this.VisitExpression(col.Expression);
                n.Alias = (SqlAlias)this.Visit(col.Alias); 
                return n; 
            }
            internal override SqlExpression VisitColumnRef(SqlColumnRef cref) { 
                if (this.ingoreExternalRefs && !this.nodeMap.ContainsKey(cref.Column)) {
                    return cref;
                }
                return new SqlColumnRef((SqlColumn)this.Visit(cref.Column)); 
            }
            internal override SqlStatement VisitDelete(SqlDelete sd) { 
                return new SqlDelete((SqlSelect)this.Visit(sd.Select), sd.SourceExpression); 
            }
            internal override SqlExpression VisitElement(SqlSubSelect elem) { 
                return this.VisitMultiset(elem);
            }
            internal override SqlExpression VisitExists(SqlSubSelect sqlExpr) {
                return new SqlSubSelect(sqlExpr.NodeType, sqlExpr.ClrType, sqlExpr.SqlType, (SqlSelect)this.Visit(sqlExpr.Select)); 
            }
            internal override SqlStatement VisitInsert(SqlInsert si) { 
                SqlInsert n = new SqlInsert(si.Table, this.VisitExpression(si.Expression), si.SourceExpression); 
                n.OutputKey = si.OutputKey;
                n.OutputToLocal = si.OutputToLocal; 
                n.Row = this.VisitRow(si.Row);
                return n;
            }
            internal override SqlSource VisitJoin(SqlJoin join) { 
                SqlSource left = this.VisitSource(join.Left);
                SqlSource right = this.VisitSource(join.Right); 
                SqlExpression cond = (SqlExpression)this.Visit(join.Condition); 
                return new SqlJoin(join.JoinType, left, right, cond, join.SourceExpression);
            } 
            internal override SqlExpression VisitValue(SqlValue value) {
                return value;
            }
            internal override SqlNode VisitMember(SqlMember m) { 
                return new SqlMember(m.ClrType, m.SqlType, (SqlExpression)this.Visit(m.Expression), m.Member);
            } 
            internal override SqlMemberAssign VisitMemberAssign(SqlMemberAssign ma) { 
                return new SqlMemberAssign(ma.Member, (SqlExpression)this.Visit(ma.Expression));
            } 
            internal override SqlExpression VisitMultiset(SqlSubSelect sms) {
                return new SqlSubSelect(sms.NodeType, sms.ClrType, sms.SqlType, (SqlSelect)this.Visit(sms.Select));
            }
            internal override SqlExpression VisitParameter(SqlParameter p) { 
                SqlParameter n = new SqlParameter(p.ClrType, p.SqlType, p.Name, p.SourceExpression);
                n.Direction = p.Direction; 
                return n; 
            }
            internal override SqlRow VisitRow(SqlRow row) { 
                SqlRow nrow = new SqlRow(row.SourceExpression);
                foreach (SqlColumn c in row.Columns) {
                    nrow.Columns.Add((SqlColumn)this.Visit(c));
                } 
                return nrow;
            } 
            internal override SqlExpression VisitScalarSubSelect(SqlSubSelect ss) { 
                return new SqlSubSelect(SqlNodeType.ScalarSubSelect, ss.ClrType, ss.SqlType, this.VisitSequence(ss.Select));
            } 
            internal override SqlSelect VisitSelect(SqlSelect select) {
                SqlSource from = this.VisitSource(select.From);
                List gex = null;
                if (select.GroupBy.Count > 0) { 
                    gex = new List(select.GroupBy.Count);
                    foreach (SqlExpression sqlExpr in select.GroupBy) { 
                        gex.Add((SqlExpression)this.Visit(sqlExpr)); 
                    }
                } 
                SqlExpression having = (SqlExpression)this.Visit(select.Having);
                List lex = null;
                if (select.OrderBy.Count > 0) {
                    lex = new List(select.OrderBy.Count); 
                    foreach (SqlOrderExpression sox in select.OrderBy) {
                        SqlOrderExpression nsox = new SqlOrderExpression(sox.OrderType, (SqlExpression)this.Visit(sox.Expression)); 
                        lex.Add(nsox); 
                    }
                } 
                SqlExpression top = (SqlExpression)this.Visit(select.Top);
                SqlExpression where = (SqlExpression)this.Visit(select.Where);
                SqlRow row = (SqlRow)this.Visit(select.Row);
                SqlExpression selection = this.VisitExpression(select.Selection); 

                SqlSelect n = new SqlSelect(selection, from, select.SourceExpression); 
                if (gex != null) 
                    n.GroupBy.AddRange(gex);
                n.Having = having; 
                if (lex != null)
                    n.OrderBy.AddRange(lex);
                n.OrderingType = select.OrderingType;
                n.Row = row; 
                n.Top = top;
                n.IsDistinct = select.IsDistinct; 
                n.IsPercent = select.IsPercent; 
                n.Where = where;
                n.DoNotOutput = select.DoNotOutput; 
                return n;
            }
            internal override SqlTable VisitTable(SqlTable tab) {
                SqlTable nt = new SqlTable(tab.MetaTable, tab.RowType, tab.SqlRowType, tab.SourceExpression); 
                this.nodeMap[tab] = nt;
                foreach (SqlColumn c in tab.Columns) { 
                    nt.Columns.Add((SqlColumn)this.Visit(c)); 
                }
                return nt; 
            }
            internal override SqlUserQuery VisitUserQuery(SqlUserQuery suq) {
                List args = new List(suq.Arguments.Count);
                foreach (SqlExpression expr in suq.Arguments) { 
                    args.Add(this.VisitExpression(expr));
                } 
                SqlExpression projection = this.VisitExpression(suq.Projection); 
                SqlUserQuery n = new SqlUserQuery(suq.QueryText, projection, args, suq.SourceExpression);
                this.nodeMap[suq] = n; 

                foreach (SqlUserColumn suc in suq.Columns) {
                    SqlUserColumn dupSuc = new SqlUserColumn(suc.ClrType, suc.SqlType, suc.Query, suc.Name, suc.IsRequired, suc.SourceExpression);
                    this.nodeMap[suc] = dupSuc; 
                    n.Columns.Add(dupSuc);
                } 
 
                return n;
            } 
            internal override SqlStoredProcedureCall VisitStoredProcedureCall(SqlStoredProcedureCall spc) {
                List args = new List(spc.Arguments.Count);
                foreach (SqlExpression expr in spc.Arguments) {
                    args.Add(this.VisitExpression(expr)); 
                }
                SqlExpression projection = this.VisitExpression(spc.Projection); 
                SqlStoredProcedureCall n = new SqlStoredProcedureCall(spc.Function, projection, args, spc.SourceExpression); 
                this.nodeMap[spc] = n;
                foreach (SqlUserColumn suc in spc.Columns) { 
                    n.Columns.Add((SqlUserColumn)this.Visit(suc));
                }
                return n;
            } 
            internal override SqlExpression VisitUserColumn(SqlUserColumn suc) {
                if (this.ingoreExternalRefs && !this.nodeMap.ContainsKey(suc)) { 
                    return suc; 
                }
                return new SqlUserColumn(suc.ClrType, suc.SqlType, suc.Query, suc.Name, suc.IsRequired, suc.SourceExpression); 
            }
            internal override SqlExpression VisitUserRow(SqlUserRow row) {
                return new SqlUserRow(row.RowType, row.SqlType, (SqlUserQuery)this.Visit(row.Query), row.SourceExpression);
            } 
            internal override SqlExpression VisitTreat(SqlUnary t) {
                return new SqlUnary(SqlNodeType.Treat, t.ClrType, t.SqlType, (SqlExpression)this.Visit(t.Operand), t.SourceExpression); 
            } 
            internal override SqlExpression VisitUnaryOperator(SqlUnary uo) {
                return new SqlUnary(uo.NodeType, uo.ClrType, uo.SqlType, (SqlExpression)this.Visit(uo.Operand), uo.Method, uo.SourceExpression); 
            }
            internal override SqlStatement VisitUpdate(SqlUpdate su) {
                SqlSelect ss = (SqlSelect)this.Visit(su.Select);
                List assignments = new List(su.Assignments.Count); 
                foreach (SqlAssign sa in su.Assignments) {
                    assignments.Add((SqlAssign)this.Visit(sa)); 
                } 
                return new SqlUpdate(ss, assignments, su.SourceExpression);
            } 
            internal override SqlStatement VisitAssign(SqlAssign sa) {
                return new SqlAssign(this.VisitExpression(sa.LValue), this.VisitExpression(sa.RValue), sa.SourceExpression);
            }
            internal override SqlExpression VisitSearchedCase(SqlSearchedCase c) { 
                SqlExpression @else = this.VisitExpression(c.Else);
                SqlWhen[] whens = new SqlWhen[c.Whens.Count]; 
                for (int i = 0, n = whens.Length; i < n; i++) { 
                    SqlWhen when = c.Whens[i];
                    whens[i] = new SqlWhen(this.VisitExpression(when.Match), this.VisitExpression(when.Value)); 
                }
                return new SqlSearchedCase(c.ClrType, whens, @else, c.SourceExpression);
            }
            internal override SqlExpression VisitClientCase(SqlClientCase c) { 
                SqlExpression expr = this.VisitExpression(c.Expression);
                SqlClientWhen[] whens = new SqlClientWhen[c.Whens.Count]; 
                for (int i = 0, n = whens.Length; i < n; i++) { 
                    SqlClientWhen when = c.Whens[i];
                    whens[i] = new SqlClientWhen(this.VisitExpression(when.Match), this.VisitExpression(when.Value)); 
                }
                return new SqlClientCase(c.ClrType, expr, whens, c.SourceExpression);
            }
            internal override SqlExpression VisitSimpleCase(SqlSimpleCase c) { 
                SqlExpression expr = this.VisitExpression(c.Expression);
                SqlWhen[] whens = new SqlWhen[c.Whens.Count]; 
                for (int i = 0, n = whens.Length; i < n; i++) { 
                    SqlWhen when = c.Whens[i];
                    whens[i] = new SqlWhen(this.VisitExpression(when.Match), this.VisitExpression(when.Value)); 
                }
                return new SqlSimpleCase(c.ClrType, expr, whens, c.SourceExpression);
            }
            internal override SqlNode VisitUnion(SqlUnion su) { 
                return new SqlUnion(this.Visit(su.Left), this.Visit(su.Right), su.All);
            } 
            internal override SqlExpression VisitExprSet(SqlExprSet xs) { 
                SqlExpression[] exprs = new SqlExpression[xs.Expressions.Count];
                for (int i = 0, n = exprs.Length; i < n; i++) { 
                    exprs[i] = this.VisitExpression(xs.Expressions[i]);
                }
                return new SqlExprSet(xs.ClrType, exprs, xs.SourceExpression);
            } 
            internal override SqlBlock VisitBlock(SqlBlock block) {
                SqlBlock nb = new SqlBlock(block.SourceExpression); 
                foreach (SqlStatement stmt in block.Statements) { 
                    nb.Statements.Add((SqlStatement)this.Visit(stmt));
                } 
                return nb;
            }
            internal override SqlExpression VisitVariable(SqlVariable v) {
                return v; 
            }
            internal override SqlExpression VisitOptionalValue(SqlOptionalValue sov) { 
                SqlExpression hasValue = this.VisitExpression(sov.HasValue); 
                SqlExpression value = this.VisitExpression(sov.Value);
                return new SqlOptionalValue(hasValue, value); 
            }
            internal override SqlExpression VisitBetween(SqlBetween between) {
                SqlBetween nbet = new SqlBetween(
                    between.ClrType, 
                    between.SqlType,
                    this.VisitExpression(between.Expression), 
                    this.VisitExpression(between.Start), 
                    this.VisitExpression(between.End),
                    between.SourceExpression 
                    );
                return nbet;
            }
            internal override SqlExpression VisitIn(SqlIn sin) { 
                SqlIn nin = new SqlIn(sin.ClrType, sin.SqlType, this.VisitExpression(sin.Expression), sin.Values, sin.SourceExpression);
                for (int i = 0, n = nin.Values.Count; i < n; i++) { 
                    nin.Values[i] = this.VisitExpression(nin.Values[i]); 
                }
                return nin; 
            }
            internal override SqlExpression VisitLike(SqlLike like) {
                return new SqlLike(
                    like.ClrType, like.SqlType, 
                    this.VisitExpression(like.Expression),
                    this.VisitExpression(like.Pattern), 
                    this.VisitExpression(like.Escape), 
                    like.SourceExpression
                    ); 
            }
            internal override SqlExpression VisitFunctionCall(SqlFunctionCall fc) {
                SqlExpression[] args = new SqlExpression[fc.Arguments.Count];
                for (int i = 0, n = fc.Arguments.Count; i < n; i++) { 
                    args[i] = this.VisitExpression(fc.Arguments[i]);
                } 
                return new SqlFunctionCall(fc.ClrType, fc.SqlType, fc.Name, args, fc.SourceExpression); 
            }
            internal override SqlExpression VisitTableValuedFunctionCall(SqlTableValuedFunctionCall fc) { 
                SqlExpression[] args = new SqlExpression[fc.Arguments.Count];
                for (int i = 0, n = fc.Arguments.Count; i < n; i++) {
                    args[i] = this.VisitExpression(fc.Arguments[i]);
                } 
                SqlTableValuedFunctionCall nfc = new SqlTableValuedFunctionCall(fc.RowType, fc.ClrType, fc.SqlType, fc.Name, args, fc.SourceExpression);
                this.nodeMap[fc] = nfc; 
                foreach (SqlColumn c in fc.Columns) { 
                    nfc.Columns.Add((SqlColumn)this.Visit(c));
                } 
                return nfc;
            }
            internal override SqlExpression VisitMethodCall(SqlMethodCall mc) {
                SqlExpression[] args = new SqlExpression[mc.Arguments.Count]; 
                for (int i = 0, n = mc.Arguments.Count; i < n; i++) {
                    args[i] = this.VisitExpression(mc.Arguments[i]); 
                } 
                return new SqlMethodCall(mc.ClrType, mc.SqlType, mc.Method, this.VisitExpression(mc.Object), args, mc.SourceExpression);
            } 
            internal override SqlExpression VisitSharedExpression(SqlSharedExpression sub) {
                SqlSharedExpression n = new SqlSharedExpression(sub.Expression);
                this.nodeMap[sub] = n;
                n.Expression = this.VisitExpression(sub.Expression); 
                return n;
            } 
            internal override SqlExpression VisitSharedExpressionRef(SqlSharedExpressionRef sref) { 
                if (this.ingoreExternalRefs && !this.nodeMap.ContainsKey(sref.SharedExpression)) {
                    return sref; 
                }
                return new SqlSharedExpressionRef((SqlSharedExpression)this.Visit(sref.SharedExpression));
            }
            internal override SqlExpression VisitSimpleExpression(SqlSimpleExpression simple) { 
                SqlSimpleExpression n = new SqlSimpleExpression(this.VisitExpression(simple.Expression));
                return n; 
            } 
            internal override SqlExpression VisitGrouping(SqlGrouping g) {
                SqlGrouping n = new SqlGrouping(g.ClrType, g.SqlType, 
                    this.VisitExpression(g.Key), this.VisitExpression(g.Group), g.SourceExpression
                    );
                return n;
            } 
            internal override SqlExpression VisitObjectType(SqlObjectType ot) {
                return new SqlObjectType(this.VisitExpression(ot.Object), ot.SqlType, ot.SourceExpression); 
            } 
            internal override SqlExpression VisitDiscriminatedType(SqlDiscriminatedType dt) {
                return new SqlDiscriminatedType(dt.SqlType, this.VisitExpression(dt.Discriminator), dt.TargetType, dt.SourceExpression); 
            }
            internal override SqlExpression VisitLift(SqlLift lift) {
                return new SqlLift(lift.ClrType, this.VisitExpression(lift.Expression), lift.SourceExpression);
            } 
            internal override SqlExpression VisitDiscriminatorOf(SqlDiscriminatorOf dof) {
                return new SqlDiscriminatorOf(this.VisitExpression(dof.Object), dof.ClrType, dof.SqlType, dof.SourceExpression); 
            } 
            internal override SqlNode VisitIncludeScope(SqlIncludeScope scope) {
                return new SqlIncludeScope(this.Visit(scope.Child), scope.SourceExpression); 
            }
        }
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System; 
using System.Collections.Generic;
using System.Data.Linq;
using System.Data.Linq.Provider;
using System.Diagnostics.CodeAnalysis; 

namespace System.Data.Linq.SqlClient { 
 
    internal class SqlDuplicator {
        DuplicatingVisitor superDuper; 

        internal SqlDuplicator()
            : this(true) {
        } 

        internal SqlDuplicator(bool ignoreExternalRefs) { 
            this.superDuper = new DuplicatingVisitor(ignoreExternalRefs); 
        }
 
        internal static SqlNode Copy(SqlNode node) {
            if (node == null)
                return null;
            switch (node.NodeType) { 
                case SqlNodeType.ColumnRef:
                case SqlNodeType.Value: 
                case SqlNodeType.Parameter: 
                case SqlNodeType.Variable:
                    return node; 
                default:
                    return new SqlDuplicator().Duplicate(node);
            }
        } 

        internal SqlNode Duplicate(SqlNode node) { 
            return this.superDuper.Visit(node); 
        }
 
        [SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Justification="These issues are related to our use of if-then and case statements for node types, which adds to the complexity count however when reviewed they are easy to navigate and understand.")]
        internal class DuplicatingVisitor : SqlVisitor {
            Dictionary nodeMap;
            bool ingoreExternalRefs; 

            internal DuplicatingVisitor(bool ignoreExternalRefs) { 
                this.ingoreExternalRefs = ignoreExternalRefs; 
                this.nodeMap = new Dictionary();
            } 

            internal override SqlNode Visit(SqlNode node) {
                if (node == null) {
                    return null; 
                }
                SqlNode result = null; 
                if (this.nodeMap.TryGetValue(node, out result)) { 
                    return result;
                } 
                result = base.Visit(node);
                this.nodeMap[node] = result;
                return result;
            } 
            internal override SqlExpression VisitDoNotVisit(SqlDoNotVisitExpression expr) {
                // duplicator can duplicate through a do-no-visit node 
                return new SqlDoNotVisitExpression(this.VisitExpression(expr.Expression)); 
            }
            internal override SqlAlias VisitAlias(SqlAlias a) { 
                SqlAlias n = new SqlAlias(a.Node);
                this.nodeMap[a] = n;
                n.Node = this.Visit(a.Node);
                n.Name = a.Name; 
                return n;
            } 
            internal override SqlExpression VisitAliasRef(SqlAliasRef aref) { 
                if (this.ingoreExternalRefs && !this.nodeMap.ContainsKey(aref.Alias)) {
                    return aref; 
                }
                return new SqlAliasRef((SqlAlias)this.Visit(aref.Alias));
            }
            internal override SqlRowNumber VisitRowNumber(SqlRowNumber rowNumber) { 
                List orderBy = new List();
 
                foreach (SqlOrderExpression expr in rowNumber.OrderBy) { 
                    orderBy.Add(new SqlOrderExpression(expr.OrderType, (SqlExpression)this.Visit(expr.Expression)));
                } 

                return new SqlRowNumber(rowNumber.ClrType, rowNumber.SqlType, orderBy, rowNumber.SourceExpression);
            }
            internal override SqlExpression VisitBinaryOperator(SqlBinary bo) { 
                SqlExpression left = (SqlExpression)this.Visit(bo.Left);
                SqlExpression right = (SqlExpression)this.Visit(bo.Right); 
                return new SqlBinary(bo.NodeType, bo.ClrType, bo.SqlType, left, right, bo.Method); 
            }
            internal override SqlExpression VisitCast(SqlUnary c) { 
                SqlExpression op = (SqlExpression)this.Visit(c.Operand);
                return new SqlUnary(SqlNodeType.Cast, c.ClrType, c.SqlType, op, c.SourceExpression);
            }
            internal override SqlExpression VisitClientQuery(SqlClientQuery cq) { 
                SqlSubSelect query = (SqlSubSelect) this.VisitExpression(cq.Query);
                SqlClientQuery nq = new SqlClientQuery(query); 
                for (int i = 0, n = cq.Arguments.Count; i < n; i++) { 
                    nq.Arguments.Add(this.VisitExpression(cq.Arguments[i]));
                } 
                for (int i = 0, n = cq.Parameters.Count; i < n; i++) {
                    nq.Parameters.Add((SqlParameter)this.VisitExpression(cq.Parameters[i]));
                }
                return nq; 
            }
            internal override SqlExpression VisitJoinedCollection(SqlJoinedCollection jc) { 
                return new SqlJoinedCollection(jc.ClrType, jc.SqlType, this.VisitExpression(jc.Expression), this.VisitExpression(jc.Count), jc.SourceExpression); 
            }
            internal override SqlExpression VisitClientArray(SqlClientArray scar) { 
                SqlExpression[] exprs = new SqlExpression[scar.Expressions.Count];
                for (int i = 0, n = exprs.Length; i < n; i++) {
                    exprs[i] = this.VisitExpression(scar.Expressions[i]);
                } 
                return new SqlClientArray(scar.ClrType, scar.SqlType, exprs, scar.SourceExpression);
            } 
            internal override SqlExpression VisitTypeCase(SqlTypeCase tc) { 
                SqlExpression disc = VisitExpression(tc.Discriminator);
                List whens = new List(); 
                foreach(SqlTypeCaseWhen when in tc.Whens) {
                    whens.Add(new SqlTypeCaseWhen(VisitExpression(when.Match), VisitExpression(when.TypeBinding)));
                }
                return new SqlTypeCase(tc.ClrType, tc.SqlType, tc.RowType, disc, whens, tc.SourceExpression); 
            }
            internal override SqlExpression VisitNew(SqlNew sox) { 
                SqlExpression[] args = new SqlExpression[sox.Args.Count]; 
                SqlMemberAssign[] bindings = new SqlMemberAssign[sox.Members.Count];
                for (int i = 0, n = args.Length; i < n; i++) { 
                    args[i] = this.VisitExpression(sox.Args[i]);
                }
                for (int i = 0, n = bindings.Length; i < n; i++) {
                    bindings[i] = this.VisitMemberAssign(sox.Members[i]); 
                }
                return new SqlNew(sox.MetaType, sox.SqlType, sox.Constructor, args, sox.ArgMembers, bindings, sox.SourceExpression); 
            } 
            internal override SqlNode VisitLink(SqlLink link) {
                SqlExpression[] exprs = new SqlExpression[link.KeyExpressions.Count]; 
                for (int i = 0, n = exprs.Length; i < n; i++) {
                    exprs[i] = this.VisitExpression(link.KeyExpressions[i]);
                }
                SqlLink newLink = new SqlLink(new object(), link.RowType, link.ClrType, link.SqlType, null, link.Member, exprs, null, link.SourceExpression); 
                this.nodeMap[link] = newLink;
                // break the potential cyclic tree by visiting these after adding to the map 
                newLink.Expression = this.VisitExpression(link.Expression); 
                newLink.Expansion = this.VisitExpression(link.Expansion);
                return newLink; 
            }
            internal override SqlExpression VisitColumn(SqlColumn col) {
                SqlColumn n = new SqlColumn(col.ClrType, col.SqlType, col.Name, col.MetaMember, null, col.SourceExpression);
                this.nodeMap[col] = n; 
                n.Expression = this.VisitExpression(col.Expression);
                n.Alias = (SqlAlias)this.Visit(col.Alias); 
                return n; 
            }
            internal override SqlExpression VisitColumnRef(SqlColumnRef cref) { 
                if (this.ingoreExternalRefs && !this.nodeMap.ContainsKey(cref.Column)) {
                    return cref;
                }
                return new SqlColumnRef((SqlColumn)this.Visit(cref.Column)); 
            }
            internal override SqlStatement VisitDelete(SqlDelete sd) { 
                return new SqlDelete((SqlSelect)this.Visit(sd.Select), sd.SourceExpression); 
            }
            internal override SqlExpression VisitElement(SqlSubSelect elem) { 
                return this.VisitMultiset(elem);
            }
            internal override SqlExpression VisitExists(SqlSubSelect sqlExpr) {
                return new SqlSubSelect(sqlExpr.NodeType, sqlExpr.ClrType, sqlExpr.SqlType, (SqlSelect)this.Visit(sqlExpr.Select)); 
            }
            internal override SqlStatement VisitInsert(SqlInsert si) { 
                SqlInsert n = new SqlInsert(si.Table, this.VisitExpression(si.Expression), si.SourceExpression); 
                n.OutputKey = si.OutputKey;
                n.OutputToLocal = si.OutputToLocal; 
                n.Row = this.VisitRow(si.Row);
                return n;
            }
            internal override SqlSource VisitJoin(SqlJoin join) { 
                SqlSource left = this.VisitSource(join.Left);
                SqlSource right = this.VisitSource(join.Right); 
                SqlExpression cond = (SqlExpression)this.Visit(join.Condition); 
                return new SqlJoin(join.JoinType, left, right, cond, join.SourceExpression);
            } 
            internal override SqlExpression VisitValue(SqlValue value) {
                return value;
            }
            internal override SqlNode VisitMember(SqlMember m) { 
                return new SqlMember(m.ClrType, m.SqlType, (SqlExpression)this.Visit(m.Expression), m.Member);
            } 
            internal override SqlMemberAssign VisitMemberAssign(SqlMemberAssign ma) { 
                return new SqlMemberAssign(ma.Member, (SqlExpression)this.Visit(ma.Expression));
            } 
            internal override SqlExpression VisitMultiset(SqlSubSelect sms) {
                return new SqlSubSelect(sms.NodeType, sms.ClrType, sms.SqlType, (SqlSelect)this.Visit(sms.Select));
            }
            internal override SqlExpression VisitParameter(SqlParameter p) { 
                SqlParameter n = new SqlParameter(p.ClrType, p.SqlType, p.Name, p.SourceExpression);
                n.Direction = p.Direction; 
                return n; 
            }
            internal override SqlRow VisitRow(SqlRow row) { 
                SqlRow nrow = new SqlRow(row.SourceExpression);
                foreach (SqlColumn c in row.Columns) {
                    nrow.Columns.Add((SqlColumn)this.Visit(c));
                } 
                return nrow;
            } 
            internal override SqlExpression VisitScalarSubSelect(SqlSubSelect ss) { 
                return new SqlSubSelect(SqlNodeType.ScalarSubSelect, ss.ClrType, ss.SqlType, this.VisitSequence(ss.Select));
            } 
            internal override SqlSelect VisitSelect(SqlSelect select) {
                SqlSource from = this.VisitSource(select.From);
                List gex = null;
                if (select.GroupBy.Count > 0) { 
                    gex = new List(select.GroupBy.Count);
                    foreach (SqlExpression sqlExpr in select.GroupBy) { 
                        gex.Add((SqlExpression)this.Visit(sqlExpr)); 
                    }
                } 
                SqlExpression having = (SqlExpression)this.Visit(select.Having);
                List lex = null;
                if (select.OrderBy.Count > 0) {
                    lex = new List(select.OrderBy.Count); 
                    foreach (SqlOrderExpression sox in select.OrderBy) {
                        SqlOrderExpression nsox = new SqlOrderExpression(sox.OrderType, (SqlExpression)this.Visit(sox.Expression)); 
                        lex.Add(nsox); 
                    }
                } 
                SqlExpression top = (SqlExpression)this.Visit(select.Top);
                SqlExpression where = (SqlExpression)this.Visit(select.Where);
                SqlRow row = (SqlRow)this.Visit(select.Row);
                SqlExpression selection = this.VisitExpression(select.Selection); 

                SqlSelect n = new SqlSelect(selection, from, select.SourceExpression); 
                if (gex != null) 
                    n.GroupBy.AddRange(gex);
                n.Having = having; 
                if (lex != null)
                    n.OrderBy.AddRange(lex);
                n.OrderingType = select.OrderingType;
                n.Row = row; 
                n.Top = top;
                n.IsDistinct = select.IsDistinct; 
                n.IsPercent = select.IsPercent; 
                n.Where = where;
                n.DoNotOutput = select.DoNotOutput; 
                return n;
            }
            internal override SqlTable VisitTable(SqlTable tab) {
                SqlTable nt = new SqlTable(tab.MetaTable, tab.RowType, tab.SqlRowType, tab.SourceExpression); 
                this.nodeMap[tab] = nt;
                foreach (SqlColumn c in tab.Columns) { 
                    nt.Columns.Add((SqlColumn)this.Visit(c)); 
                }
                return nt; 
            }
            internal override SqlUserQuery VisitUserQuery(SqlUserQuery suq) {
                List args = new List(suq.Arguments.Count);
                foreach (SqlExpression expr in suq.Arguments) { 
                    args.Add(this.VisitExpression(expr));
                } 
                SqlExpression projection = this.VisitExpression(suq.Projection); 
                SqlUserQuery n = new SqlUserQuery(suq.QueryText, projection, args, suq.SourceExpression);
                this.nodeMap[suq] = n; 

                foreach (SqlUserColumn suc in suq.Columns) {
                    SqlUserColumn dupSuc = new SqlUserColumn(suc.ClrType, suc.SqlType, suc.Query, suc.Name, suc.IsRequired, suc.SourceExpression);
                    this.nodeMap[suc] = dupSuc; 
                    n.Columns.Add(dupSuc);
                } 
 
                return n;
            } 
            internal override SqlStoredProcedureCall VisitStoredProcedureCall(SqlStoredProcedureCall spc) {
                List args = new List(spc.Arguments.Count);
                foreach (SqlExpression expr in spc.Arguments) {
                    args.Add(this.VisitExpression(expr)); 
                }
                SqlExpression projection = this.VisitExpression(spc.Projection); 
                SqlStoredProcedureCall n = new SqlStoredProcedureCall(spc.Function, projection, args, spc.SourceExpression); 
                this.nodeMap[spc] = n;
                foreach (SqlUserColumn suc in spc.Columns) { 
                    n.Columns.Add((SqlUserColumn)this.Visit(suc));
                }
                return n;
            } 
            internal override SqlExpression VisitUserColumn(SqlUserColumn suc) {
                if (this.ingoreExternalRefs && !this.nodeMap.ContainsKey(suc)) { 
                    return suc; 
                }
                return new SqlUserColumn(suc.ClrType, suc.SqlType, suc.Query, suc.Name, suc.IsRequired, suc.SourceExpression); 
            }
            internal override SqlExpression VisitUserRow(SqlUserRow row) {
                return new SqlUserRow(row.RowType, row.SqlType, (SqlUserQuery)this.Visit(row.Query), row.SourceExpression);
            } 
            internal override SqlExpression VisitTreat(SqlUnary t) {
                return new SqlUnary(SqlNodeType.Treat, t.ClrType, t.SqlType, (SqlExpression)this.Visit(t.Operand), t.SourceExpression); 
            } 
            internal override SqlExpression VisitUnaryOperator(SqlUnary uo) {
                return new SqlUnary(uo.NodeType, uo.ClrType, uo.SqlType, (SqlExpression)this.Visit(uo.Operand), uo.Method, uo.SourceExpression); 
            }
            internal override SqlStatement VisitUpdate(SqlUpdate su) {
                SqlSelect ss = (SqlSelect)this.Visit(su.Select);
                List assignments = new List(su.Assignments.Count); 
                foreach (SqlAssign sa in su.Assignments) {
                    assignments.Add((SqlAssign)this.Visit(sa)); 
                } 
                return new SqlUpdate(ss, assignments, su.SourceExpression);
            } 
            internal override SqlStatement VisitAssign(SqlAssign sa) {
                return new SqlAssign(this.VisitExpression(sa.LValue), this.VisitExpression(sa.RValue), sa.SourceExpression);
            }
            internal override SqlExpression VisitSearchedCase(SqlSearchedCase c) { 
                SqlExpression @else = this.VisitExpression(c.Else);
                SqlWhen[] whens = new SqlWhen[c.Whens.Count]; 
                for (int i = 0, n = whens.Length; i < n; i++) { 
                    SqlWhen when = c.Whens[i];
                    whens[i] = new SqlWhen(this.VisitExpression(when.Match), this.VisitExpression(when.Value)); 
                }
                return new SqlSearchedCase(c.ClrType, whens, @else, c.SourceExpression);
            }
            internal override SqlExpression VisitClientCase(SqlClientCase c) { 
                SqlExpression expr = this.VisitExpression(c.Expression);
                SqlClientWhen[] whens = new SqlClientWhen[c.Whens.Count]; 
                for (int i = 0, n = whens.Length; i < n; i++) { 
                    SqlClientWhen when = c.Whens[i];
                    whens[i] = new SqlClientWhen(this.VisitExpression(when.Match), this.VisitExpression(when.Value)); 
                }
                return new SqlClientCase(c.ClrType, expr, whens, c.SourceExpression);
            }
            internal override SqlExpression VisitSimpleCase(SqlSimpleCase c) { 
                SqlExpression expr = this.VisitExpression(c.Expression);
                SqlWhen[] whens = new SqlWhen[c.Whens.Count]; 
                for (int i = 0, n = whens.Length; i < n; i++) { 
                    SqlWhen when = c.Whens[i];
                    whens[i] = new SqlWhen(this.VisitExpression(when.Match), this.VisitExpression(when.Value)); 
                }
                return new SqlSimpleCase(c.ClrType, expr, whens, c.SourceExpression);
            }
            internal override SqlNode VisitUnion(SqlUnion su) { 
                return new SqlUnion(this.Visit(su.Left), this.Visit(su.Right), su.All);
            } 
            internal override SqlExpression VisitExprSet(SqlExprSet xs) { 
                SqlExpression[] exprs = new SqlExpression[xs.Expressions.Count];
                for (int i = 0, n = exprs.Length; i < n; i++) { 
                    exprs[i] = this.VisitExpression(xs.Expressions[i]);
                }
                return new SqlExprSet(xs.ClrType, exprs, xs.SourceExpression);
            } 
            internal override SqlBlock VisitBlock(SqlBlock block) {
                SqlBlock nb = new SqlBlock(block.SourceExpression); 
                foreach (SqlStatement stmt in block.Statements) { 
                    nb.Statements.Add((SqlStatement)this.Visit(stmt));
                } 
                return nb;
            }
            internal override SqlExpression VisitVariable(SqlVariable v) {
                return v; 
            }
            internal override SqlExpression VisitOptionalValue(SqlOptionalValue sov) { 
                SqlExpression hasValue = this.VisitExpression(sov.HasValue); 
                SqlExpression value = this.VisitExpression(sov.Value);
                return new SqlOptionalValue(hasValue, value); 
            }
            internal override SqlExpression VisitBetween(SqlBetween between) {
                SqlBetween nbet = new SqlBetween(
                    between.ClrType, 
                    between.SqlType,
                    this.VisitExpression(between.Expression), 
                    this.VisitExpression(between.Start), 
                    this.VisitExpression(between.End),
                    between.SourceExpression 
                    );
                return nbet;
            }
            internal override SqlExpression VisitIn(SqlIn sin) { 
                SqlIn nin = new SqlIn(sin.ClrType, sin.SqlType, this.VisitExpression(sin.Expression), sin.Values, sin.SourceExpression);
                for (int i = 0, n = nin.Values.Count; i < n; i++) { 
                    nin.Values[i] = this.VisitExpression(nin.Values[i]); 
                }
                return nin; 
            }
            internal override SqlExpression VisitLike(SqlLike like) {
                return new SqlLike(
                    like.ClrType, like.SqlType, 
                    this.VisitExpression(like.Expression),
                    this.VisitExpression(like.Pattern), 
                    this.VisitExpression(like.Escape), 
                    like.SourceExpression
                    ); 
            }
            internal override SqlExpression VisitFunctionCall(SqlFunctionCall fc) {
                SqlExpression[] args = new SqlExpression[fc.Arguments.Count];
                for (int i = 0, n = fc.Arguments.Count; i < n; i++) { 
                    args[i] = this.VisitExpression(fc.Arguments[i]);
                } 
                return new SqlFunctionCall(fc.ClrType, fc.SqlType, fc.Name, args, fc.SourceExpression); 
            }
            internal override SqlExpression VisitTableValuedFunctionCall(SqlTableValuedFunctionCall fc) { 
                SqlExpression[] args = new SqlExpression[fc.Arguments.Count];
                for (int i = 0, n = fc.Arguments.Count; i < n; i++) {
                    args[i] = this.VisitExpression(fc.Arguments[i]);
                } 
                SqlTableValuedFunctionCall nfc = new SqlTableValuedFunctionCall(fc.RowType, fc.ClrType, fc.SqlType, fc.Name, args, fc.SourceExpression);
                this.nodeMap[fc] = nfc; 
                foreach (SqlColumn c in fc.Columns) { 
                    nfc.Columns.Add((SqlColumn)this.Visit(c));
                } 
                return nfc;
            }
            internal override SqlExpression VisitMethodCall(SqlMethodCall mc) {
                SqlExpression[] args = new SqlExpression[mc.Arguments.Count]; 
                for (int i = 0, n = mc.Arguments.Count; i < n; i++) {
                    args[i] = this.VisitExpression(mc.Arguments[i]); 
                } 
                return new SqlMethodCall(mc.ClrType, mc.SqlType, mc.Method, this.VisitExpression(mc.Object), args, mc.SourceExpression);
            } 
            internal override SqlExpression VisitSharedExpression(SqlSharedExpression sub) {
                SqlSharedExpression n = new SqlSharedExpression(sub.Expression);
                this.nodeMap[sub] = n;
                n.Expression = this.VisitExpression(sub.Expression); 
                return n;
            } 
            internal override SqlExpression VisitSharedExpressionRef(SqlSharedExpressionRef sref) { 
                if (this.ingoreExternalRefs && !this.nodeMap.ContainsKey(sref.SharedExpression)) {
                    return sref; 
                }
                return new SqlSharedExpressionRef((SqlSharedExpression)this.Visit(sref.SharedExpression));
            }
            internal override SqlExpression VisitSimpleExpression(SqlSimpleExpression simple) { 
                SqlSimpleExpression n = new SqlSimpleExpression(this.VisitExpression(simple.Expression));
                return n; 
            } 
            internal override SqlExpression VisitGrouping(SqlGrouping g) {
                SqlGrouping n = new SqlGrouping(g.ClrType, g.SqlType, 
                    this.VisitExpression(g.Key), this.VisitExpression(g.Group), g.SourceExpression
                    );
                return n;
            } 
            internal override SqlExpression VisitObjectType(SqlObjectType ot) {
                return new SqlObjectType(this.VisitExpression(ot.Object), ot.SqlType, ot.SourceExpression); 
            } 
            internal override SqlExpression VisitDiscriminatedType(SqlDiscriminatedType dt) {
                return new SqlDiscriminatedType(dt.SqlType, this.VisitExpression(dt.Discriminator), dt.TargetType, dt.SourceExpression); 
            }
            internal override SqlExpression VisitLift(SqlLift lift) {
                return new SqlLift(lift.ClrType, this.VisitExpression(lift.Expression), lift.SourceExpression);
            } 
            internal override SqlExpression VisitDiscriminatorOf(SqlDiscriminatorOf dof) {
                return new SqlDiscriminatorOf(this.VisitExpression(dof.Object), dof.ClrType, dof.SqlType, dof.SourceExpression); 
            } 
            internal override SqlNode VisitIncludeScope(SqlIncludeScope scope) {
                return new SqlIncludeScope(this.Visit(scope.Child), scope.SourceExpression); 
            }
        }
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK