Entity Framework-как проверить, существует ли таблица?

Я использую Entity Framework с первым подходом кода. Базовый класс DbContext имеет функции для создания и удаления базы данных, а также для проверки ее существования.

Я хочу проверить, существует ли специальная таблица (сущность) или нет. Возможно ли это с реализацией framework или мне нужно написать пользовательские методы? Если мне нужно написать свою собственную реализацию, какой будет самый общий подход для этого?

Спасибо за любую помощь.

5 ответов


Если вам нужно проверить наличие таблицы, вы должны вызвать пользовательский код SQL:

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;

имя таблицы по умолчанию определяется как имя DbSet exposed в производном контексте, но имя по умолчанию может быть переопределено либо fluent API ToTable способ или Table Примечания данные.

выполнение этого в общем виде не является чем-то предполагаемым в первом подходе кода. Для этого потребуется просматривать метаданные и вручную исследовать, к какой таблице относится объект сопоставлено-это может быть довольно сложно, потому что сущность может быть сопоставлена с несколькими таблицами. Код first не предлагает доступ к метаданным. Вы должны преобразовать DbContext to ObjectContext и выберите MetadataWorkspace.

Edit:

преобразование DbContext to ObjectContext используйте этот:

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

Я не могу добавить комментарий в предыдущем посте. Я использую SQL Compact, и я не знаю схему таблицы. Я использую этот код для проверки таблицы, это почти то же самое, что и в предыдущем посте, но он работает для любой таблицы.

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

альтернативный метод; он не так эффективен, как у Ладислава, но он не привязан к SQL Server:

bool CheckTableExists()
{
    try
    {
        context.YourTable.Count();
        return true;
    }
    catch (Exception)
    {
        return false;
    }
}

предположение: SQL Server

ловить любое старое исключение при запросе DbSet не означает, что таблица не существует.

запрос DbSet где таблица не существует скинет EntityCommandExecutionException с внутренним исключением типа SqlException. Это внутреннее исключение имеет ErrorNumber собственность.

номер ошибки 208 читает (источник):

недопустимое имя объекта '%.* ls'.


Я думаю, что следующий код немного более понятен.

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