Search code examples
c#sql-serverscriptdom

Create a visitor for generic statement in TransactSql.ScriptDom


With TransactSql.ScriptDom, it is possible to view object model of an SQL statement by extending the TSqlFragmentVisitor class. For each statement type, there is a separate Visit method which can be overridden. But I want to put exactly the same code into each Visit, of each type. I need something like a generic Visit, for all kinds of Statements. How can I do that?

using Microsoft.SqlServer.TransactSql.ScriptDom;
using System.Reflection;
public class CustomVisitor: TSqlFragmentVisitor
{
    private void DoSomething(dynamic obj)
    {
        foreach (var property in obj.GetType().
            GetProperties(BindingFlags.Public | BindingFlags.Instance))
        {
            // Recursively analyse object model to find specific objects
        }
    }

    // Create table
    public override void Visit(CreateTableStatement node)
    {
        DoSomething(node);
        base.Visit(node);
    }

    // Create view
    public override void Visit(CreateViewStatement node)
    {
        DoSomething(node);
        base.Visit(node);
    }

    // ...
    // Huge number of Visit for different types of statement
}

Solution

  • I did found a generic method for all kinds of Statements: Visit(TSqlStatement node). The code now looks like this:

        using Microsoft.SqlServer.TransactSql.ScriptDom;
        using System.Reflection;
        public class CustomVisitor : TSqlFragmentVisitor
        {
            private void DoSomething(dynamic obj)
            {
                foreach (var property in obj.GetType().
                    GetProperties(BindingFlags.Public | BindingFlags.Instance))
                {
                    // Recursively analyse object model to find specific objects
                }
            }
    
            // Generic statement
            public override void Visit(TSqlStatement node)
            {
                DoSomething(node);
                base.Visit(node);
            }
        }
    // Generic statement
    public override void Visit(TSqlStatement node)
    {
        DoSomething(node);
        base.Visit(node);
    }
    

    }