Esquema

Obteniendo el esquema de una Tabla de SQL Server


Hay lugares en los que la generación automática de código no está del todo bien vista. Sin embargo, utilizando las herramientas apropiadas, un generador de código simple puede ahorrar muchas horas de trabajo.
Esta introducción parece no tener demasiado que ver con el título del artículo, pero en realidad está bastante relacionada.

La razón es la siguiente: hemos visto previamente, cuando hablábamos del patrón DAO, que la necesidad de crear entidades DTO para cada tabla de la base de datos era una realidad.

Bien, hasta aquí todo claro. Pero… ¿y si fuese posible crear estos ficheros de forma automática? ¿Cómo? Preguntándole a la base de datos qué tablas y campos posee, y generando a partir de ellos el código necesario para implementar un DTO. Y todo ello sin despeinarnos.
Este artículo trata de hacer un breve inciso en el principio en el que se basa dicha generación de código. Únicamente veremos el mecanismo por el cual preguntar a la base de datos por estos parámetros. Hecho esto, podremos crear un fichero fuente con facilidad.

Para comenzar, declararemos un método que, a partir de una conexión de tipo Sql Server, devuelva un DataSet con una colección de tablas, cuyo nombre sea el propio nombre de la tabla y sus campos sean los datos de dichas tablas que queramos obtener.


      public DataSet ObtenerEsquemaBD(SqlConnection Conexion)
        {

Lo primero que haremos será abrir la conexión, con su correspondiente comprobación de nulos (es decir, si la conexión existe o no).

            try
            {
                if (!(Conexion == null))
                {
                    // Abrimos la conexión
                    if (!(Conexion.State == ConnectionState.Open))
                    {
                        Conexion.Open();
                    }

Seguidamente, crearemos un DataTable para almacenar los nombres de las tablas de la base de datos, así como un DataSet y un DataAdapter para almacenar los datos de las consultas. Utilizaremos una cadena de texto para almacenar las sentencias de las consultas.

                    // Creamos un DataTable para almacenar los nombres de las tablas de la base de datos
                    DataTable dtTablas = new DataTable();

                    // Creamos un DataSet y un DataAdapter para obtener los datos
                    DataSet ds = new DataSet();
                    SqlDataAdapter da = new SqlDataAdapter();

                    // Declaramos una cadena para la consulta
                    string sSQL;

Indicaremos que queremos obtener las tablas de la Base de Datos, y lo almacenamos en el DataTable destinado a ello mediante el DataAdapter

                    sSQL = "SELECT TABLE_NAME as Tabla FROM Information_Schema.Tables";
                    da.SelectCommand = new SqlCommand(sSQL, Conexion);
                    da.Fill(dtTablas);

Ahora recorreremos la tabla que contiene los nombres de cada tabla, realizando una consulta por cada una de ellas. En esta consulta obtendremos datos como el nombre de columna, si admite nulos o no, el tipo de dato…

                    foreach (DataRow dr in dtTablas.Rows)
                    {
                        if(!dr.IsNull("Tabla"))
                        {
                            DataTable dt = new DataTable();
                            sSQL = ("SELECT TABLE_CATALOG as Db, TABLE_NAME as Tabla, ORDINAL_POSITION as Posicion, COLUMN_NAME as Columna" +
                            ", IS_NULLABLE as AdmiteNulos, DATA_TYPE as TipoDatos, CHARACTER_MAXIMUM_LENGTH as MaxChar FROM Infor" +
                            "mation_Schema.Columns WHERE TABLE_NAME = \'"
                                        + (dr["Tabla"].ToString() + "\'"));
                            da.SelectCommand = new SqlCommand(sSQL, Conexion);
                            da.Fill(dt);

                            // Hecha la consulta, añadimos la tabla obtenida por este procedimiento a nuestro DataSet
                            dt.TableName = dr["Tabla"].ToString();
                            ds.Tables.Add(dt);
                        }
                    }

Finalmente, cerramos la conexión y devolvemos el DataSet

                    Conexion.Close();
                    return ds;
                }
                else
                {
                    Conexion.Close();
                    return null;
                }
            }
            catch (Exception ex)
            {
                throw(ex);
            }
        }

El resultado aparecerá en el DataSet, almacenando, por lo tanto, un esquema por cada tabla.

090501Tablas