Estoy obteniendo tablas, columnas del servidor Sql y la base de datos mysql, así que tengo algo de duplicación de código.

Quiero mantener una función común en la que me gustaría manejar la conexión del servidor mysql y sql (apertura y cierre) junto con la eliminación del objeto de conexión.

Esta es mi función común para obtener tablas de Mysql y ms sql :

public List<Tables> GetTables(string databaseName, string connectionString, string type)
{
    var list = new List<Tables>();
    if (type == 'mysql')
    {
        using (MySqlConnection con = new MySqlConnection(connectionString))
        {
            con.Open();
            list = con.GetSchema("Tables").AsEnumerable()
                              .Select
                                      (
                                          t => new Tables
                                          {
                                              Name = t["TABLE_SCHEMA"].ToString() + "." + t[2].ToString()
                                          }
                                      ).ToList();
            con.Close();
        }
    }
    else
    {
        using (SqlConnection con = new SqlConnection(connectionString))
        {
            con.Open();
            list = con.GetSchema("Tables").AsEnumerable()
                             .Select
                                     (
                                         t => new Tables
                                         {
                                             Name = t["TABLE_SCHEMA"].ToString() + "." + t[2].ToString()
                                         }
                                     ).ToList();
            con.Close();
        }
    }
    return list;
}

Así que tengo una duplicación de código arriba y lo mismo en caso de obtener columnas:

public List<Columns> GetColumns(string connectionString, string database, string table, string type)
{
    if (type == 'mysql')
    {
        using (MySqlConnection conn = new MySqlConnection(connectionString))
        {
            con.Open();
            var list = conn.GetSchema("Columns", columnRestrictions).AsEnumerable()
                           .Select
                           (
                                col => new
                                {
                                   //column details 
                                }
                           ).ToList();
            conn.Close();
        }
    }
    using (SqlConnection conn = new SqlConnection(connectionString))
    {
        conn.Open();
        if (conn.State == ConnectionState.Open)
        {
            var list = conn.GetSchema("Columns", columnRestrictions).AsEnumerable()
                           .Select
                           (
                                col => new
                                {
                                   //column details 
                                }
                           ).ToList();
            conn.Close();
            return list;
        }
        return null;
    }
}

Entonces, ¿alguien puede guiarme sobre cómo evitar la duplicación del código anterior y mantener 1 función común que abrirá y cerrará la conexión junto con la eliminación del objeto de conexión para que pueda llamarlo mientras obtengo tablas y columnas?

0
Learning-Overthinker-Confused 15 dic. 2016 a las 10:46

2 respuestas

La mejor respuesta

Tanto MySqlConnection como SqlConnection heredan de DbConnection.

public List<Tables> GetTables(string databaseName, string connectionString, string type)
{
    var connection = connectionFactory.GetConnection(connectionString, type);

    return connection.GetTables(connection);
}

public List<Tables> GetColumns(string databaseName, string connectionString, string type)
{
    var connection = connectionFactory.GetConnection(connectionString, type);

    return connection.GetColumns(connection);
}

private IEnumerable<Table> GetTables(DbConnection connection)
{
    connection.Open();
    list = con.GetSchema("Tables").AsEnumerable()
              .Select(t => new Tables
              {
                   Name = t["TABLE_SCHEMA"].ToString() + "." + t[2].ToString()
              }).ToList();
    connection.Close();
 }

private IEnumerable<Table> GetColumns(DbConnection connection)
{
    connection.Open();
    list = con.GetSchema("COLUMNS").AsEnumerable()
              .Select(t => new Tables
              {
                   Name = t["COLUMN_SCHEMA"].ToString() + "." + t[2].ToString()
              }).ToList();
    connection.Close();
 }

public class ConnectionFactory
{
     public DbConnection GetConnection(string connectionString, string type)
     {
           switch(type)
           {
                case "mysql":
                     return new MySqlConnection(connectionString);
                case "mssql":
                     return new SqlConnection(connectionString);
                default:
                     throw new UnsupportedException($"{type} not supported.");
           }

     }
}

Y supongo que necesita ambas conexiones en la misma aplicación, y que no es solo "en caso de que necesite cambiar de proveedor de base de datos". Típicamente, crearía una implementación por tipo de base de datos y la abstraería mediante una interfaz.

2
Michael 15 dic. 2016 a las 10:51

Probablemente debería encapsular la creación de la conexión en una función separada y solo eso.

0
Vitaliy Kalinin 15 dic. 2016 a las 09:18