2010-09-28 3 views
5

Gibt es eine Möglichkeit, die DataType-Length-Informationen der Datenbankspalte angesichts der EntityType einer Tabelle zu erhalten?Entity Framework - wie Datenbankspalten-Datentyp aus Metadaten erhalten

Beispiel SQL (SQL Server), die Sie gerade sehen, ausführen können, um welche Informationen Ich suche:

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; 

Die letzten drei Spalten enthalten die Daten, die Ich mag würde den Zugang zu haben, weil ich bin etwas Dokumentation erzeugen. Ein Beispiel für die Dokumentation ist: Entity Framework löst standardmäßig eine Exception aus, wenn eine Zeichenfolge für eine Eigenschaft festgelegt wird, die ihre Länge nicht unterstützt. Ein Entwickler ohne Zugriff auf die Datenbankmetadaten hat in diesem Fall eine Herausforderung mit der Auffindbarkeit von Längenanforderungen.

Danke, Aaron

Antwort

3

Leider nein.

Auch wenn diese Informationen korrekt in der SSDL (d Definition die Storage-Schema-Sprache) erfaßt wird, gibt es keine öffentliche API in EF geht von C-Space (konzeptioneller Modell) Immobilie zu S-Space (Speichermodell) Spalt.

Wenn Ihr Modell einfach ist, können Sie diese Informationen möglicherweise mit dem EF-Metadaten-Arbeitsbereich und einigen einfachen Heuristiken ableiten, aber sobald die Dinge ein wenig kompliziert werden, werden diese Heuristiken zusammenbrechen.

Ihre einzige Option zu diesem Zeitpunkt ist, Code zu schreiben MSL (Mapping oder CS-Space) Dateien zu interpretieren, und dass mit den MetadataWorkspace in Verbindung verwenden, um von C-Space zu S-Space zu gehen.

EDIT: wie von KristoferA hingewiesen, haben Sie oft das Attribut auf der C-Space-Eigenschaft, so dass Sie direkt zu diesem gehen können. Leider ist das nicht immer der Fall, und oft kommt es mit der Datenbank nicht in Einklang.

+0

Aber ... es gibt Attribute konzeptionellen Modell, das diese Informationen für die Felder enthalten, wo sie gelten. Unter der Annahme, dass die Informationen auf dem neuesten Stand gehalten werden, können Sie sie von der CSDL laden, anstatt nach Mappings usw. suchen zu müssen. – KristoferA

+0

Absolut. Ich wollte dies erwähnen ... –

+0

Übrigens, wenn diese Attribute nicht mehr synchron sind, ist es ein Kinderspiel, sie mit dem Modellvergleich in meinem Add-In ... (http://huagati.blogspot.com) zu aktualisieren /2010/07/introducing-model-comparer-for-entity.html) – KristoferA

0

Ich bin ziemlich sicher, dass Julie Lerman's book deckt, wie Maxlength, zumindest ein Werkzeug, um dagegen zu validieren, durch Änderungen in der POCO-Erstellung. Kapitel 13, beginnt um Seite 356. Beispiel 13-12 deckt, es beginnt mit

string MaxLengthValidation(EdmProperty prop)... 

es urheberrechtlich geschütztes Material, damit ich nicht/es wird geschnitten einfügen, aber ich hoffe, dass Sie eine Kopie ihres Buches kaufen und Hol dir die Infos.

0

Ja, das ist möglich: (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