Entity Framework - How to check if table exists?

China☆狼群 提交于 2019-11-27 21:11:18

If you need to check existence of the table you must call custom SQL code:

bool exists = context.Database
                     .SqlQuery<int?>(@"
                         SELECT 1 FROM sys.tables AS T
                         INNER JOIN sys.schemas AS S ON T.schema_id = S.schema_id
                         WHERE S.Name = 'SchemaName' AND T.Name = 'TableName'")
                     .SingleOrDefault() != null;

Table name is defined by default as the name of DbSet exposed on your derived context but the default name can be overriden either by fluent API's ToTable method or Table data annotation.

Doing this in the generic way is not something supposed in code first approach. That will require browsing metadata and manually explore to which table is the entity mapped - this can be pretty complex because entity can be mapped to multiple tables. Code first doesn't offer access to metadata. You must convert DbContext to ObjectContext and browse MetadataWorkspace.

Edit:

To convert DbContext to ObjectContext use this:

ObjectContext objContext = ((IObjectContextAdapter)dbContext).ObjectContext;

I can't add comment to previous post. I'm using SQL Compact and I don't know schema of the table. I'm using this code to check for table It's pretty the same that in previous post but It works for any table.

    /// <summary>
    /// Check if data table is exist in application
    /// </summary>
    /// <typeparam name="T">Class of data table to check</typeparam>
    /// <param name="db">DB Object</param>
    public static bool CheckTableExists<T>(this ModelLocker db) where T : class
    {
        try
        {
            db.Set<T>().Count();
            return true;

        }
        catch (Exception)
        {
            return false;
        }
    }

Assumption: SQL Server

Catching any old exception when querying the DbSet does not mean the table does not exist.

Querying a DbSet where the table does not exist will throw an EntityCommandExecutionException with an inner exception of type SqlException. That inner exception has an ErrorNumber property.

Error number 208 reads (source):

Invalid object name '%.*ls'.

An alternative method; it's not as efficient as Ladislav's, but it's not tied to SQL Server (edited to add Where clause to address performance issue):

bool CheckTableExists()
{
    try
    {
        context.YourTable.Where(s => s.<yourKeyField> = <impossible value>).Count();
        return true;
    }
    catch (Exception)
    {
        return false;
    }
}

I think following code is a little bit more understandable.

using(YourDbEntities db = new YourDbEntities()) 
{
  bool IsExists = db.Database
   .SqlQuery <int?> (@"
    SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES 
    WHERE TABLE_NAME = '" + yourTableName + "'
    ")
    .FirstOrDefault() > 0;

    return IsExists;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!