Entity Framework – Obtener lista de tablas

Eso es. Es bastante simple. Tengo un edmx y quiero poder consultarlo dinámicamente para las tablas y (con suerte), comstackr dinámicamente con esa tabla. ¿Es eso posible?

=========

ACTUALIZAR:

He incluido todas las tablas de DB, pero no vistas o SP, en el contexto. Tenemos muchas tablas que escriben información (con id). Entonces, por ejemplo, colores o tipo de archivo o tipo de protocolo. Quiero poder llevar a cabo una consulta de tipo (archivo) para las tablas que pueden contener la información de tipo (Archivo, Tipo de archivo) y devolverla con id.

Entonces, puedo buscar … Business Unit (o Color, o File) y el código se activará y buscará el contexto para BusinessUnit (o Color o File) y BusinessUnitType (o ColorType o FileType). Si encuentra cualquiera de los dos, lo consultará y devolverá todas las filas para que pueda ver si contiene información de tipo (lo definiré más adelante para que solo devuelva los campos ID y Descripción, Abreviatura o Nombre, así como para limitar filas, etc.) y poder encontrar la identificación asociada para un particular en particular.

Para su primera pregunta sobre cómo enumerar las tablas en la base de datos, este código las obtendrá para usted, por supuesto, las que se han importado a su EDM, que necesariamente no son todas las tablas en su almacén de datos.

var tableNames = context.MetadataWorkspace.GetItems(DataSpace.SSpace) .Select(t => t.Name) .ToList(); 

Este código causará una InvalidOperationException con este mensaje:
El espacio ‘SSpace’ no tiene una colección asociada
Y eso es porque, a diferencia de CSpace, SSpace (ssdl) no se carga hasta que se necesita. y tratar de leerlos con MetadataWorkspace no cuenta como necesario. Es necesario durante la comstackción de consultas, luego nuevamente en la materialización del objeto. Entonces, para engañar al MetadataWorkspace y cargarlo para nosotros, debemos ejecutar una consulta como la que se muestra a continuación justo antes de ejecutar la consulta principal que nos da los nombres de las tablas.

 string temp = ((ObjectQuery)context.[EntitySetName]).ToTraceString(); 

Puede leer más desde aquí: Truco rápido para forzar MetadataWorkspace ItemCollections para cargar

Sin embargo, si su intención es construir una consulta dinámica contra sus tablas de tipos, entonces no necesita perder el tiempo con SSpace, debe obtenerlo desde el CSpace (Modelo Conceptual). A continuación se muestra un código de ejemplo sobre cómo crear una consulta dinámica con solo tener una parte del nombre de la tabla:

 ObjectResult GetAllTypes(string name) { using (TypeEntities context = new TypeEntities()) { MetadataWorkspace metadataWorkspace = context.MetadataWorkspace; EntityContainer container = metadataWorkspace.GetItems (DataSpace.CSpace).First(); string namespaceName = metadataWorkspace.GetItems (DataSpace.CSpace).First().NamespaceName; string setName = string.Empty; string entityName = name + "Type"; EntitySetBase entitySetBase = container.BaseEntitySets .FirstOrDefault(set => set.ElementType.Name == entityName); if (entitySetBase != null) { setName = entitySetBase.Name; } EntityType entityType = metadataWorkspace .GetItem(namespaceName + "." + entityName, DataSpace.CSpace); StringBuilder stringBuilder = new StringBuilder().Append("SELECT entity "); stringBuilder .Append(" FROM " + container.Name.Trim() + "." + setName + " AS entity "); string eSQL = stringBuilder.ToString(); ObjectQuery query = context.CreateQuery(eSQL); ObjectResult results = query.Execute(MergeOption.AppendOnly); return results; } } 

Explicación del código: Mi suposición fue que los nombres de las tablas de tipo terminan en “Tipo” como un postfijo (por ejemplo, ColorType), por lo que puede llamar a GetAllType (“Color”) y buscar ColorType EntityObject en su modelo y le dará todo el valores posibles. El código puede parecer aterrador, pero es bastante simple. Básicamente, todo lo que hace es obtener toda la información requerida de MetaData (como nombre de EntitySet, nombre de espacio de nombres, etc.) en función del parámetro del método y luego crear una consulta EntitySQL sobre la marcha, luego ejecutarla y devolver el resultados.

Este código de muestra de la publicación ¿Qué tablas están en mi modelo EF? Y mi base de datos?

 using (var dbContext = new YourDbContext()) { var metadata = ((IObjectContextAdapter)dbContext).ObjectContext.MetadataWorkspace; var tables = metadata.GetItemCollection(DataSpace.SSpace) .GetItems() .Single() .BaseEntitySets .OfType() .Where(s => !s.MetadataProperties.Contains("Type") || s.MetadataProperties["Type"].ToString() == "Tables"); foreach (var table in tables) { var tableName = table.MetadataProperties.Contains("Table") && table.MetadataProperties["Table"].Value != null ? table.MetadataProperties["Table"].Value.ToString() : table.Name; var tableSchema = table.MetadataProperties["Schema"].Value.ToString(); Console.WriteLine(tableSchema + "." + tableName); } } 

En caso de que esto ayude, los saqué de una de mis clases ObjectContextExtension.

Puede consultar su contexto de objeto y obtener los nombres de la siguiente manera. Siéntete libre de modificar esto como quieras.

 public static class ObjectContextExtensions { public static string GetEntitySetName(this ObjectContext theContext, T eo) where T : EntityObject { string entitySetName = ""; if (eo.EntityKey != null) { entitySetName = eo.EntityKey.EntitySetName; } else { string className = typeof(T).Name; var container = theContext.MetadataWorkspace.GetEntityContainer(theContext.DefaultContainerName, DataSpace.CSpace); entitySetName = (from meta in container.BaseEntitySets where meta.ElementType.Name == className select meta.Name ).First(); } return entitySetName; } public static IEnumerable GetEntitySets(this ObjectContext theContext) { var container = theContext.MetadataWorkspace .GetEntityContainer( theContext.DefaultContainerName, DataSpace.CSpace); return container.BaseEntitySets; } public static IEnumerable GetObjectQueries(this ObjectContext theContext) { IEnumerable queries = from pd in theContext .GetType() .GetProperties() where pd.PropertyType .IsSubclassOf(typeof(ObjectQuery)) select (ObjectQuery)pd.GetValue(theContext, null); return queries; } } 

Cuando lo usas:

 IEnumerable lookAtMe = context.GetEntitySets(); //ElementType (type of entity the set represents) //Entity Set Name //Other fun goodies ;) //Example of how to get the entity set to query on it. File f = new File(); //or some entity you selected. f = context.Files.FirstOrDefault(); string name = context.GetEntitySetName(f); 

El otro que dejé fue GetObjectQueries y simplemente devuelve todas las ObjectQueries, que son las cosas en su contexto que consulta. context.SomeTable o context.Products.

No estoy seguro de lo que está haciendo, por lo que podría haber una mejor manera de hacerlo … una vez que actualice su objective final lo editaré en consecuencia.