2010-09-28 20 views
5

¿Hay alguna forma de obtener la información de la longitud de DataType de la columna de base de datos dada EntityType de una tabla?Entity Framework: cómo obtener el tipo de datos de columna de base de datos de metadatos

Ejemplo SQL (SQL Server) que se puede ejecutar para ver exactamente qué información Busco:

select 
    sys.tables.name as 'Table Name', 
    sys.columns.name as 'Column Name', 
    sys.systypes.name as 'DataType', 
    sys.columns.max_length as 'Max Length', 
    sys.columns.precision as 'Precision' 
from 
    sys.columns, sys.systypes, sys.tables 
where 
    sys.columns.system_type_id = sys.systypes.xtype 
    and sys.systypes.name <> 'sysname' 
    and sys.tables.type = 'U' 
    and sys.tables.name <> 'sysdiagrams' 
    and sys.columns.object_id=sys.tables.object_id 
order by 
    sys.tables.name, sys.columns.column_id; 

Las 3 últimas columnas contienen los datos que me gustaría tener acceso a porque soy generando alguna documentación. Un ejemplo de razón para la documentación es: Entity Framework arrojará una excepción por defecto si una cadena se establece en una propiedad que no puede soportar su longitud. Un desarrollador sin acceso a los metadatos de la base de datos tiene un desafío con la detectabilidad de los requisitos de longitud en este caso.

Gracias, Aaron

Respuesta

3

Desafortunadamente no.

Incluso si esa información es capturada correctamente en el SSDL (es decir, el lenguaje de definición de esquemas de almacenamiento) no hay ninguna API pública de EF para ir de C-Space (modelo conceptual) Propiedad de S-Space columna (modelo de almacenamiento).

Si su modelo es simple, tal vez pueda inferir esa información, utilizando el espacio de metadatos EF y algunas heurísticas simples, pero una vez que las cosas se complican un poco, esas heurísticas se descomponen.

Su única opción en ese momento es escribir código para interpretar MSL archivos (o mapeo CS-Space), y el uso que en conjunto con el MetadataWorkspace pasar de C-Space a S-Space.

EDIT: Como se indica en KristoferA a menudo tiene el atributo en la propiedad C-Space, por lo que puede ir directamente a eso. Lamentablemente, ese no es siempre el caso, y a menudo no se sincroniza con la base de datos.

+0

... Pero hay atributos modelo conceptual que contienen esa información para los campos donde se aplica. Suponiendo que la información se mantenga actualizada, puede cargarla desde el CSDL en lugar de tener que buscar asignaciones, etc. – KristoferA

+0

Absolutamente. Quería mencionar esto ... –

+0

Por cierto, si/cuando esos atributos no se sincronizan es muy fácil actualizarlos de nuevo con el comparador de modelos en mi complemento ... (http://huagati.blogspot.com /2010/07/introducing-model-comparer-for-entity.html) – KristoferA

0

Estoy bastante seguro de que Julie Lerman's book cubre cómo obtener maxlength, al menos una herramienta para validarlo, haciendo cambios en la creación de POCO. Capítulo 13, comienza alrededor de la página 356. Ejemplo 13-12 cubre, que se inicia con el material

string MaxLengthValidation(EdmProperty prop)... 

que es con derechos de autor, así que no cortar/pegar, pero espero que usted puede comprar una copia de su libro y obtener la información.

0

Sí, esto es posible: (EF6.1)

<Extension> 
Public Function GetColumns(Of TEntity)(Db As IObjectContextAdapter) As List(Of DataColumn) 
    Dim oMetadata As MetadataWorkspace 
    Dim oObjects As ObjectItemCollection 
    Dim oContext As ObjectContext 
    Dim oColumn As DataColumn 
    Dim oQuery As Func(Of EdmProperty, Boolean) 
    Dim oType As EntityType 

    GetColumns = New List(Of DataColumn) 

    oContext = Db.ObjectContext 
    oMetadata = oContext.MetadataWorkspace 
    oObjects = oMetadata.GetItemCollection(DataSpace.OSpace) 

    oType = oMetadata.GetItems(Of EntityType)(DataSpace.OSpace). 
    Single(Function(EntityType As EntityType) oObjects.GetClrType(EntityType) Is GetType(TEntity)) 

    oQuery = Function(EdmProperty As EdmProperty) EdmProperty.DeclaringType.Name = oType.Name 

    oType.Properties.ToList.ForEach(Sub(Column As EdmProperty) 
            oColumn = New DataColumn With 
               { 
               .AutoIncrement = Column.IsStoreGeneratedIdentity, 
               .AllowDBNull = Column.Nullable, 
               .ColumnName = Column.Name, 
               .DataType = Column.PrimitiveType.ClrEquivalentType, 
               .Caption = Column.Name 
               } 

            If oColumn.DataType Is GetType(String) Then 
             oColumn.MaxLength = Column.MaxLength.GetValueOrDefault 
            Else 
             oColumn.MaxLength = -1 
            End If 

            GetColumns.Add(oColumn) 
            End Sub) 
End Function 
Cuestiones relacionadas