枚举Entity Framework类中的列信息 [英] Enumerating column information from an Entity Framework class
问题描述
我有一个sql数据库的实体框架模型,我想以编程方式(vb.net)列出每个表的所有列和列规范。我从下面的代码开始,但是我不确定我是否在正确的轨道上,我也无法检测"自动编号"列,也无法找到存储外键列名称的位置。
/>
        Dim s As String
      Dim spk As String
      Dim pge As PangeaEntities = New PangeaEntities
      Dim mdw As Data.Metadata.Edm.MetadataWorkspace = pge.MetadataWorkspace
     对于每个实体在mdw.GetItemCollection(Data.Metadata.Edm.DataSpace.CSpace)中          如果entities.BuiltInTypeKind = Metadata.Edm.BuiltInTypeKind.EntityType那么
              Dim entity As System.Data.Metadata.Edm.EntityType = DirectCast(entities,System.Data.Metadata.Edm.EntityType)
              '主要会员               For Each pk In entity.KeyMembers
                  spk = spk& vbCrLf& "PK:" &安培; pk.Name
               接着
                "Coumns
                s =""
             对于每个成员In entity.Members
                 如果member.BuiltInTypeKind = Metadata.Edm.BuiltInTypeKind.EdmProperty则为                       'DB Column
                      s& = vbCrLf& member.Name
                        "数据类型
                        s& =" | Datatype =" &安培; member.TypeUsage.EdmType.Name
                        '列设置
                      For each facet in member.TypeUsage.Facets
                          s& =" |" &安培; facet.Name& " =" &安培; facet.Value
                       接着
                    ElseIf member.BuiltInTypeKind = Metadata.Edm.BuiltInTypeKind.NavigationProperty Then                       '外键或其他
                 否则
                        '不确定我们还能得到什么呢                  结束如果
             接着
                MsgBox(entity.Name& vbCrLf& spk& vbCrLf& s)
         结束如果
     下一步
这是您可以使用的快速示例(创建一个新的控制台应用程序,添加指向Northwind的EDMX,添加客户和订单表):
进口
System.Data.Metadata.Edm
进口
System.Data.EntityClient
模块
Module1
Sub Main()
Dim s 作为 字符串 = ""
Dim db As 新 NorthwindEntities
'PART 1 - 确定自动编号字段
'以这种方式加载元数据工作区也会带来S空间,而使用
'db.MetadataWorkspace在调用GetItemCollection时会抛出异常对于S空间
Dim mdw = CType (db.Connection,EntityConnection).GetMetadataWorkspace()
Dim items = mdw.GetItemCollection( DataSpace.SSpace)
对于 每个 实体 在 items.OfType( EntityType)()
对于 每个 成员 在 entity.Members .OfType( EdmProperty)()
'DB列
s& = vbCrLf& member.Name
s& = vbTab&
" StoreGeneratedPattern:"
Dim item As Facet = < span style ="color:#0000ff; font-size:x-small"> Nothing
如果 member.TypeUsage.Facets.TryGetValue( " StoreGeneratedPattern" , True ,item) 然后
s& =
DirectCast (item.Value,StoreGeneratedPattern).ToString()& Chr(13)
否则
s& =
"不存在"
结束 如果
下一页
< span style ="font-size:x-small">
MsgBox
s =
""
< span style ="color:#0000ff; font-size:x-small">下一步
<字体大小= 2>
'PART 2 - 确定外键
items = mdw.GetItemCollection(DataSpace.CSpace)
对于 每个 实体 在 items.OfType( EntityType)()
对于 每个 navProp 在 实体.Members.OfType( NavigationProperty)()
s& = navProp.FromEndMember.RelationshipMultiplicity.ToString() &
"到" & navProp.ToEndMember.RelationshipMultiplicity.ToString()
s& =
"来自" &的关系navProp.FromEndMember.Name& "到" & navProp.ToEndMember.Name
s& =
< span style ="color:#a31515; font-size:x-small"> "由" & navProp.RelationshipType.FullName& vbCrLf
下一页
下一页
MsgBox
结束 Sub
结束
模块
有一点需要注意的是,此示例假设您在C和S空间之间按列名称进行1:1映射。 事物是StoreGenerated的事实没有在C空间中表示,所以你必须走S空间才能得到它。 我不认为两者之间的映射信息是公开的,所以如果你的列名在C和S之间不相同,那么这种方法将不起作用。
希望有所帮助,
乔纳森
Hi,
I have an entity framework model of an sql database and I would like to programmatically (vb.net) list all columns and the column spec for each tables. I started with the code below but I am not sure if I am on the right track, also I cannot detect 'auto-number' columns and cannot find where the foreign key column names are stored.
Dim s As String
Dim spk As String
Dim pge As PangeaEntities = New PangeaEntities
Dim mdw As Data.Metadata.Edm.MetadataWorkspace = pge.MetadataWorkspace
For Each entities In mdw.GetItemCollection(Data.Metadata.Edm.DataSpace.CSpace)
If entities.BuiltInTypeKind = Metadata.Edm.BuiltInTypeKind.EntityType Then
Dim entity As System.Data.Metadata.Edm.EntityType = DirectCast(entities, System.Data.Metadata.Edm.EntityType)
'Primary Keysmember
spk = ""
For Each pk In entity.KeyMembers
spk = spk & vbCrLf & "PK: " & pk.Name
Next
'Coumns
s = ""
For Each member In entity.Members
If member.BuiltInTypeKind = Metadata.Edm.BuiltInTypeKind.EdmProperty Then
'DB Column
s &= vbCrLf & member.Name
'Datatype
s &= "|Datatype=" & member.TypeUsage.EdmType.Name
'Column settings
For Each facet In member.TypeUsage.Facets
s &= "|" & facet.Name & "=" & facet.Value
Next
ElseIf member.BuiltInTypeKind = Metadata.Edm.BuiltInTypeKind.NavigationProperty Then
'Foreign key or other
Else
'Not sure what else we can get
End If
Next
MsgBox(entity.Name & vbCrLf & spk & vbCrLf & s)
End If
Next
Here's a quick sample you can use (create a new console app, add an EDMX that points to Northwind, add the customers and orders table):
Imports
System.Data.Metadata.Edm
Imports
System.Data.EntityClient
Module
Module1
Sub Main()
Dim s As String = ""
Dim db As New NorthwindEntities
'PART 1 - Determine Auto-number fields
'loading the Metadata workspace this way brings in the S-space as well, whereas using
'db.MetadataWorkspace would throw an exception when we call GetItemCollection for the S-space
Dim mdw = CType(db.Connection, EntityConnection).GetMetadataWorkspace()
Dim items = mdw.GetItemCollection(DataSpace.SSpace)
For Each entity In items.OfType(Of EntityType)()
For Each member In entity.Members.OfType(Of EdmProperty)()
'DB Column
s &= vbCrLf & member.Name
s &= vbTab &
"StoreGeneratedPattern: "
Dim item As Facet = Nothing
If member.TypeUsage.Facets.TryGetValue("StoreGeneratedPattern", True, item) Then
s &=
DirectCast(item.Value, StoreGeneratedPattern).ToString() & Chr(13)
Else
s &=
"Not present"
End If
Next
MsgBox(s)
s =
""
Next
'PART 2 - Determine foreign keys
items = mdw.GetItemCollection(DataSpace.CSpace)
For Each entity In items.OfType(Of EntityType)()
For Each navProp In entity.Members.OfType(Of NavigationProperty)()
s &= navProp.FromEndMember.RelationshipMultiplicity.ToString() &
" to " & navProp.ToEndMember.RelationshipMultiplicity.ToString()
s &=
" relationship from " & navProp.FromEndMember.Name & " to " & navProp.ToEndMember.Name
s &=
" defined by " & navProp.RelationshipType.FullName & vbCrLf
Next
Next
MsgBox(s)
End Sub
End
Module
One thing to note is that this sample assumes you have a 1:1 mapping between your C and S space in terms of column names. The fact that something is StoreGenerated isn't represented in the C-space, so you have to walk the S-space to get it. I don't think the mapping info between the two is exposed publicly, so if your column names are not identical between C and S then this approach won't work.
Hope that helps,
Jonathan
这篇关于枚举Entity Framework类中的列信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!