是否有办法使用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;
}
}
我希望有一种方法不涉及捕获异常。
答案 0 :(得分:19)
好吧,您可以使用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 :(得分:1)
对Kyle的答案的小改进,因为不同的数据库(例如oracle vs ms-sql-server)将table-name列放在“Tables”表中的不同索引中:
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