Есть ли способ с помощью ADO.NET определить, существует ли таблица в базе данных, которая работает с любым поставщиком данных? - PullRequest
6 голосов
/ 20 августа 2010

Есть ли способ с помощью ADO.NET определить, существует ли таблица в базе данных, которая работает с любым поставщиком данных?

В настоящее время я делаю что-то вроде этого:

bool DoesTableExist(string tableName)
{
    DbCommand command = this.dbConnection.CreateCommand();
    command.CommandText = "SELECT 1 FROM " + tableName;
    try
    {
        using (DbDataReader reader = command.ExecuteReader())
        {
            return true;
        }
    }
    catch (DbException)
    {
        return false;
    }
}

Я надеюсь, что есть способ, который не предполагает отлов исключений.

Ответы [ 2 ]

19 голосов
/ 20 августа 2010

Ну, вы можете использовать метод Connection.GetSchema("TABLES").

Возвращает DataTable, который будет содержать строки всех таблиц в вашей БД. Отсюда вы можете проверить это и посмотреть, существует ли таблица.

Затем можно сделать следующий шаг:

    private static bool DoesTableExist(string TableName)
    {
        using (SqlConnection conn = 
                     new SqlConnection("Data Source=DBServer;Initial Catalog=InitialDB;User Id=uname;Password=pword;"))
        {
            conn.Open();

            DataTable dTable = conn.GetSchema("TABLES", 
                           new string[] { null, null, "MyTableName" });

            return dTable.Rows.Count > 0;
        }
    }

Если вы используете .NET 3.5, то вы также можете сделать это методом расширения.

1 голос
/ 26 января 2017

Небольшое улучшение ответа Кайла за счет того факта, что разные базы данных (например, oracle vs ms-sql-server) помещают столбец имени таблицы в другой индекс в таблице «Таблицы»:

    public static bool CheckIfTableExists(this DbConnection connection, string tableName) //connection = ((DbContext) _context).Database.Connection;
    {
        if (connection == null)
            throw new ArgumentException(nameof(connection));

        if (connection.State == ConnectionState.Closed)
            connection.Open();

        var tableInfoOnTables = connection //0
            .GetSchema("Tables")
            .Columns
            .Cast<DataColumn>()
            .Select(x => x.ColumnName?.ToLowerInvariant() ?? "")
            .ToList();

        var tableNameColumnIndex = tableInfoOnTables.FindIndex(x => x.Contains("table".ToLowerInvariant()) && x.Contains("name".ToLowerInvariant())); //order
        tableNameColumnIndex = tableNameColumnIndex == -1 ? tableInfoOnTables.FindIndex(x => x.Contains("table".ToLowerInvariant())) : tableNameColumnIndex; //order
        tableNameColumnIndex = tableNameColumnIndex == -1 ? tableInfoOnTables.FindIndex(x => x.Contains("name".ToLowerInvariant())) : tableNameColumnIndex; //order

        if (tableNameColumnIndex == -1)
            throw new ApplicationException("Failed to spot which column holds the names of the tables in the dictionary-table of the DB");

        var constraints = new string[tableNameColumnIndex + 1];
        constraints[tableNameColumnIndex] = tableName;

        return connection.GetSchema("Tables", constraints)?.Rows.Count > 0;
    }
    //0 different databases have different number of columns and different names assigned to them
    //
    //     SCHEMA,TABLENAME,TYPE -> oracle
    //     table_catalog,table_schema,table_name,table_type -> mssqlserver
    //
    //  we thus need to figure out which column represents the tablename and target that one
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...