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

Я использую Entity Framework с использованием метода Code First. Базовый класс bool exists = context . База данных . 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 (сущность) или нет. Возможно ли это с реализацией фреймворка или мне нужно написать собственные методы? Если мне нужно написать свою собственную реализацию, какой был бы общий подход для этого?

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

c#,sql,ef-code-first,entity-framework-4.1,

20

Ответов: 5


32 ов принято

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

ToTable

Имя таблицы определяется по умолчанию как имя Tableвыставленного в вашем производном контексте, но имя по умолчанию может быть переопределено либо с помощью свободного API- DbContextметода, либо с помощью Tableаннотации данных.

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

Редактировать:

Для того, чтобы преобразовать DbContextв ObjectContextиспользовать это:

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

3

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

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

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

2

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

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

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

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

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


0

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

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;
}
C #, SQL, эф-код-первых, сущность-рамки-4,1,
Похожие вопросы