代码之家  ›  专栏  ›  技术社区  ›  Ergwun

是否有方法使用ADO.NET来确定数据库中是否存在与任何数据提供程序一起使用的表?

  •  6
  • Ergwun  · 技术社区  · 15 年前

    是否有方法使用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 回复  |  直到 9 年前
        1
  •  19
  •   Glenn Slayden    9 年前

    好吧,你可以用 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,那么您也可以将其作为扩展方法。

        2
  •  1
  •   XDS    9 年前

    对Kyle的答案进行了细微改进,因为不同的数据库(例如Oracle和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