public class OleDbHelper : DbHelper<OleDbConnection>
{
}

public class SqlDbHelper : DbHelper<SqlConnection>
{
}

public class DbHelper<TC> where TC : DbConnection
{
    public static DbDataReader ExecuteReader(string connectionString, string sql, params DbParameter[] pars)
    {
        return ExecuteCommand<TC, DbDataReader>(
            connectionString, sql,
            (Cx, Cd) =>
            {
                Cx.Open();
                return Cd.ExecuteReader(CommandBehavior.CloseConnection);
            },
            pars);
    }

    public static int Execute(string connectionString, string sql, params DbParameter[] pars)
    {
        return ExecuteCommand<TC, int>(
            connectionString, sql,
            (Cx, Cd) =>
            {
                Cx.Open();
                try
                {
                    return Cd.ExecuteNonQuery();
                }
                finally
                {
                    Cx.Close();
                }
            },
            pars);
    }

    public static T ExecuteScalar<T>(string connectionString, string sql, params DbParameter[] pars)
    {
        return ExecuteCommand<TC, T>(
            connectionString, sql,
            (Cx, Cd) =>
            {
                Cx.Open();
                try
                {
                    var Obj = Cd.ExecuteScalar();
                    if (Obj == DBNull.Value)
                        return default(T);
                    else
                        return (T)Obj;
                }
                finally
                {
                    Cx.Close();
                }
            },
            pars);
    }

    static T3 ExecuteCommand<T, T3>(string connectionString, string sql, Func<T, DbCommand, T3> action, params DbParameter[] pars) where T : DbConnection
    {
        T3 ReturnValue;

        var Cx = Activator.CreateInstance<T>();
        Cx.ConnectionString = connectionString;

        using (var Cd = Cx.CreateCommand())
        {
            Cd.CommandText = sql;

            if (pars != null && pars.Length > 0)
                Cd.Parameters.AddRange(pars);

            ReturnValue = action(Cx, Cd);
        }

        return ReturnValue;
    }
}