2010-09-28 29 views
5

有沒有一種方法來獲得數據庫列的DataType長度信息給定一個表的EntityType?實體框架 - 如何從元數據獲取數據庫列的數據類型

實例SQL(SQL Server)的,您可以運行看正是我要尋找什麼樣的信息:

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; 

最後3列包含,我想有機會獲得,因爲我的數據生成一些文檔。該文檔的一個示例原因是:如果在不支持長度的屬性上設置字符串,Entity Framework將默認引發異常。無法訪問數據庫元數據的開發人員在這種情況下對長度要求的可發現性提出了挑戰。

感謝, 亞倫

回答

3

遺憾的是沒有。

即使該信息在SSDL中正確捕獲(即存儲模式定義語言),EF中也沒有公共API從C-Space(概念模型)屬性轉到S-Space(存儲模型)列。

如果你的模型很簡單,你可以使用EF元數據工作空間和一些簡單的啓發式來推斷這些信息,但是一旦事情變得有點複雜,那些啓發式就會崩潰。

你在這一點上唯一的選擇就是寫代碼來解釋MSL(映射或CS-Space)文件,並使用與MetadataWorkspace一起去從C-SpaceS-Space

編輯:正如KristoferA所指出的那樣,您經常在C-Space屬性中擁有該屬性,因此您可以直接轉到該屬性。不幸的是,情況並非總是如此,並且經常與數據庫不同步。

+0

但是......有包含該信息的地方應用領域的概念模型的屬性。假設信息保持最新,您可以從CSDL加載它,而不必查找映射等。 – KristoferA 2010-09-29 05:52:17

+0

絕對。我的意思是提到這個... – 2010-09-29 15:40:23

+0

順便說一句,如果/當這些屬性不同步時,使用我的插件中的模型比較器再次更新它們是一件輕而易舉的事情(http://huagati.blogspot.com /2010/07/introducing-model-comparer-for-entity.html) – KristoferA 2010-09-30 06:53:03

0

我很確定Julie Lerman's book涵蓋了如何通過更改POCO的創建來獲得maxlength,至少一個工具來驗證它。第13章,開始頁356例13-12覆蓋它周圍,它與

string MaxLengthValidation(EdmProperty prop)... 

受版權保護材料開始,所以我不會剪切/粘貼,但我希望你能買她的書的副本,獲取信息。

0

是的,這是可能的:(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