Entity Framework - Как проверить, существует ли таблица? - PullRequest
23 голосов
/ 23 мая 2011

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

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

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

Ответы [ 5 ]

33 голосов
/ 23 мая 2011

Если вам нужно проверить существование таблицы, вы должны вызвать пользовательский код 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, отображаемое в вашем производном контексте, но имя по умолчанию может быть переопределено с помощью метода ToTable свободного API или Table аннотации данных.

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

Edit:

Чтобы преобразовать DbContext в ObjectContext, используйте это:

ObjectContext objContext = ((IObjectContextAdapter)dbContext).ObjectContext;
4 голосов
/ 16 февраля 2016

Я не могу добавить комментарий к предыдущему сообщению. Я использую 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;
        }
    }
2 голосов
/ 27 января 2017

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

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

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

Ошибка 208 чтения ( источник ):

Неверное имя объекта "%. * Ls".

2 голосов
/ 20 марта 2015

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

bool CheckTableExists()
{
    try
    {
        context.YourTable.Where(s => s.<yourKeyField> = <impossible value>).Count();
        return true;
    }
    catch (Exception)
    {
        return false;
    }
}
1 голос
/ 25 августа 2018

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

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