实体框架 - 如何从元数据中获取数据库列数据类型

时间:2010-09-28 17:31:34

标签: sql-server entity-framework types metadata

有没有办法在给定表的EntityType?

的情况下获取数据库列DataType长度信息

您可以运行示例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列包含我想要访问的数据,因为我正在生成一些文档。文档的一个示例原因是:如果在不支持其长度的属性上设置字符串,则实体框架将默认抛出异常。在这种情况下,无法访问数据库元数据的开发人员对长度要求的可发现性提出了挑战。

谢谢, 亚伦

3 个答案:

答案 0 :(得分:3)

不幸的是没有。

即使在SSDL中正确捕获了该信息(即存储架构定义语言),EF中也没有公共API可以从C-Space(概念模型)属性转到S-Space(存储模型) )专栏。

如果您的模型很简单,您可以使用EF元数据工作区和一些简单的启发式方法推断出这些信息,但是一旦事情变得有点复杂,那些启发式算法就会崩溃。

此时您唯一的选择是编写代码来解释MSL(映射或CS-Space)文件,并将其与MetadataWorkspace结合使用,以便从C-Space转到{{ 1}}。

编辑:正如KristoferA指出的那样,您经常拥有C-Space属性的属性,因此您可以直接转到该属性。不幸的是,并非总是如此,并且通常它与数据库不同步。

答案 1 :(得分:0)

我很确定Julie Lerman's book涵盖了如何通过在POCO创建中进行更改来获取maxlength,至少是一个验证它的工具。第13章,从第356页开始。例13-12涵盖了它,它以

开头
 string MaxLengthValidation(EdmProperty prop)...

它是受版权保护的材料,因此我不会剪切/粘贴它,但我希望您可以购买她的书的副本并获取信息。

答案 2 :(得分: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