2010-08-20 12 views
6

Herhangi bir veri sağlayıcısıyla çalışan bir veritabanında bir tablo olup olmadığını belirlemek için ADO.NET'i kullanmanın bir yolu var mı?Herhangi bir veri sağlayıcısıyla çalışan bir veritabanında bir tablo olup olmadığını belirlemek için ADO.NET'i kullanmanın bir yolu var mı?

Şu anda böyle bir şey yapıyorum:

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; 
    } 
} 

ben yakalamak istisnalar içermeyen bir yolu olduğunu umut ediyorum.

+0

Muhtemelen bu soruyu soruyorsunuz çünkü orada kod kokusu tespit ettiniz, bu yüzden bunu bir iltifat olarak kabul edin: Akış kontrolü istisnaları kullanmak en iyi uygulama değildir. – ErikE

cevap

16

Connection.GetSchema("TABLES") yöntemini kullanabilirsiniz.

Bu, DB'nizdeki tüm tabloların satırlarını içeren bir DataTable değerini döndürür. Buradan buna karşı kontrol edebilir ve tablonun var olup olmadığını görebilirsiniz.

Bu

sonra bir adım daha alınabilir:

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 kullanıyorsanız, o zaman sen de bu bir uzantısı yöntemi yapabilirsiniz.

+0

Harika. İş güzel mi, teşekkürler. – Ergwun

+0

Bir işlem açıkken çalışmaz (bkz .: https://social.msdn.microsoft.com/Forums/en-US/b4a458d0-65bd-40fb-bc60-c7ed8e94517f/sqlconnectiongetschema-exceptions-when-in-a- işlem? forumu = adodotnetdataproviders). – Dejan

1

farklı veritabanları (örneğin ms-sql sunucu vs oracle) "Tablolar" tablosunda farklı bir endekste tablo adı sütununu yerleştirmek gerçeğini hesaba Kyle'ın yanıta Küçük gelişme:

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 
İlgili konular