2011-05-23 31 views
19

Estoy usando Entity Framework con el enfoque Code First. La clase base DbContext tiene funciones para crear y eliminar la base de datos, así como para verificar su existencia.Entity Framework - ¿Cómo verificar si existe una tabla?

Quiero comprobar si existe una tabla especial (entidad) o no. ¿Es posible con una implementación de framework o necesito escribir métodos personalizados? Si necesito escribir mi propia implementación, ¿cuál sería el enfoque más genérico para hacer eso?

Gracias por cualquier ayuda.

Respuesta

31

Si es necesario comprobar la existencia de la tabla que debe llamar a código SQL personalizada:

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; 

Nombre de la tabla se define por defecto como el nombre de DbSet expuesta en su contexto derivado pero el nombre por defecto puede ser anulado ya sea por el método fluido de la API ToTable o la anotación de datos Table.

Hacer esto de forma genérica no es algo que se suponga en el primer enfoque del código. Esto requerirá examinar los metadatos y explorar manualmente a qué tabla está asignada la entidad; esto puede ser bastante complejo porque la entidad se puede mapear en varias tablas. El código primero no ofrece acceso a los metadatos. Debe convertir DbContext en ObjectContext y examinar MetadataWorkspace.

Editar:

Para convertir DbContext-ObjectContext uso esto:

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

¿Cómo puedo convertir DbContext en ObjectContext? He buscado diferentes enfoques para verificar la existencia de una tabla. ¿Hay alguna diferencia entre su solución y a) SELECCIONE * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'TheSchema' Y TABLE_NAME = 'TheTable')) ob) SELECT * FROM sys.objects WHERE object_id = OBJECT_ID (N '[dbo] . [TableName] ') Y escriba in (N'U')? ¿Podría explicar las ventajas/desventajas? Preferiría usar una forma de conformidad más estándar. – 0xbadf00d

+0

En general, todas estas selecciones SQL consultan la misma información; esa es solo una manera diferente de obtener el mismo resultado. –

+0

¿Qué significa tipo (N'U ')? Su versión ignora el esquema de la tabla, ¿verdad? – 0xbadf00d

2

Un método alternativo; que no es tan eficiente como Ladislav de, pero no está atado a SQL Server:

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

Eso es muy poco recomendable en cuanto a rendimiento ... – petric

4

No puedo añadir comentario al post anterior. Estoy usando SQL Compact y no sé el esquema de la tabla. Estoy usando este código para verificar la tabla. Es bastante similar a la publicación anterior, pero funciona para cualquier tabla.

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

Supuesto: SQL Server

La captura de cualquier excepción de edad cuando se consulta la DbSet no significa que la tabla no existe.

Al consultar un DbSet donde no existe la tabla arrojará un EntityCommandExecutionException con una excepción interna del tipo SqlException. Esa excepción interna tiene una propiedad ErrorNumber.

Número de error 208 lee (source):

nombre de objeto no válido '%. * Ls'.

Cuestiones relacionadas