Entity Framework. Как проверить, существует ли таблица?
Я использую Entity Framework с использованием метода Code First. Базовый класс DbContext имеет функции для создания и удаления базы данных, а также для проверки ее существования.
Я хочу проверить, существует ли специальная таблица (сущность) или нет. Возможно ли это с реализацией фреймворка или мне нужно написать собственные методы? Если мне нужно написать свою собственную реализацию, какой был бы общий подход для этого?
Спасибо за любую помощь.
Ответы
Ответ 1
Если вам нужно проверить наличие таблицы, вы должны вызвать собственный код 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
, которое отображается в вашем производном контексте, но имя по умолчанию может быть переопределено либо с помощью свободного API ToTable
, либо Table
аннотации данных.
Выполнение этого в общем виде не является чем-то, что предполагается в первом подходе кода. Это потребует просмотра метаданных и вручную изучить, к какой таблице отображается объект - это может быть довольно сложно, поскольку объект может быть сопоставлен с несколькими таблицами. Сначала код не предоставляет доступ к метаданным. Вы должны преобразовать DbContext
в ObjectContext
и просмотреть MetadataWorkspace
.
Edit:
Для преобразования DbContext
в ObjectContext
используйте это:
ObjectContext objContext = ((IObjectContextAdapter)dbContext).ObjectContext;
Ответ 2
Я не могу добавить комментарий к предыдущему сообщению. Я использую 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;
}
}
Ответ 3
Альтернативный метод; он не так эффективен, как Ladislav, но он не привязан к SQL Server:
bool CheckTableExists()
{
try
{
context.YourTable.Count();
return true;
}
catch (Exception)
{
return false;
}
}
Ответ 4
Предположение: SQL Server
Захват любого старого исключения при запросе DbSet
не означает, что таблица не существует.
Запрос DbSet
, где таблица не существует, вызовет EntityCommandExecutionException
с внутренним исключением типа SqlException
. Это внутреннее исключение имеет свойство ErrorNumber
.
Номер ошибки 208 читает (источник):
Недопустимое имя объекта '%. * ls'.