【问题标题】:Map Entity Framework code properties to database columns (CSpace to SSpace)将实体框架代码属性映射到数据库列(CSpace 到 SSpace)
【发布时间】:2014-06-11 10:28:45
【问题描述】:

我正在尝试实现一个属性,该属性可以应用于我的代码优先实体框架数据模型中的属性,以指示创建数据库时将应用的唯一约束。我有read about extracting EF table mapping information 使用为EF 6.1 公开的映射API,我有read about implementing a custom attribute to indicate which properties represent a natural key。但是,除非我误读了代码,否则我认为这仅在 CLR 属性名称(OSpace / CSpace)与 SQL 列名称(SSpace)匹配时才有效。我希望能够在我的唯一键中包含关联属性(外键),例如此示例中的 EnumList:

Public Class EnumValue
   Public Property EnumValueId As Integer
   Public Property Sequence As Integer
   Public Overridable Property Label As TranslatedString
   <MaxLength(5), MyUnique()> _
   Public Property Value As String
   <MyUnique()> _
   Public Overridable Property EnumList As EnumList
End Class

我从这么多代码开始,它基于有关映射表名称的链接文章

Dim ws = DirectCast(context, System.Data.Entity.Infrastructure.IObjectContextAdapter).ObjectContext.MetadataWorkspace
Dim oSpace = ws.GetItemCollection(Core.Metadata.Edm.DataSpace.OSpace)
Dim entityTypes = oSpace.GetItems(Of EntityType)()
Dim entityContainer = ws.GetItems(Of EntityContainer)(DataSpace.CSpace).Single()
Dim mapping = ws.GetItems(Of EntityContainerMapping)(DataSpace.CSSpace).Single.EntitySetMappings
For Each setType In entityTypes
   Dim cSpaceEntitySet = entityContainer.EntitySets.Single(Function(t) t.ElementType.Name = setType.Name)
   Dim sSpaceEntitySet = mapping.Single(Function(t) t.EntitySet Is cSpaceEntitySet)
   Dim tableInfo = sSpaceEntitySet.EntityTypeMappings.Single.Fragments.Single
   Dim tableName = If(tableInfo.StoreEntitySet.Table, tableInfo.StoreEntitySet.Name)
   Dim schema = tableInfo.StoreEntitySet.Schema

这足以获得我需要的有关表名的信息,但现在我需要以某种方式将 CLR 属性名链接到 SQL 列名,而且理解 EF 元数据框架的速度很慢。我希望更熟悉它的人可以加快速度。

【问题讨论】:

    标签: .net vb.net entity-framework


    【解决方案1】:

    我不确定它是否完整或可靠,但我终于制定了适用于我的第一个测试用例的代码:

    Dim ws = DirectCast(context, System.Data.Entity.Infrastructure.IObjectContextAdapter).ObjectContext.MetadataWorkspace
    Dim oSpace = ws.GetItemCollection(Core.Metadata.Edm.DataSpace.OSpace)
    Dim entityTypes = oSpace.GetItems(Of EntityType)()
    Dim entityContainer = ws.GetItems(Of EntityContainer)(DataSpace.CSpace).Single()
    Dim entityMapping = ws.GetItems(Of EntityContainerMapping)(DataSpace.CSSpace).Single.EntitySetMappings
    Dim associations = ws.GetItems(Of EntityContainerMapping)(DataSpace.CSSpace).Single.AssociationSetMappings
    For Each setType In entityTypes
       Dim cSpaceEntitySet = entityContainer.EntitySets.SingleOrDefault( _
          Function(t) t.ElementType.Name = setType.Name)
       If cSpaceEntitySet Is Nothing Then Continue For ' Derived entities will be skipped
       Dim sSpaceEntitySet = entityMapping.Single(Function(t) t.EntitySet Is cSpaceEntitySet)
       Dim tableInfo As MappingFragment
       If sSpaceEntitySet.EntityTypeMappings.Count = 1 Then
          tableInfo = sSpaceEntitySet.EntityTypeMappings.Single.Fragments.Single
       Else
          ' Select only the mapping (esp. PropertyMappings) for the base class
          tableInfo = sSpaceEntitySet.EntityTypeMappings.Where(Function(m) m.IsOfEntityTypes.Count _
             = 1 AndAlso m.IsOfEntityTypes.Single.Name Is setType.Name).Single().Fragments.Single
       End If
       Dim tableName = If(tableInfo.StoreEntitySet.Table, tableInfo.StoreEntitySet.Name)
       Dim schema = tableInfo.StoreEntitySet.Schema
       Dim clrType = Type.GetType(setType.FullName)
       Dim uniqueCols As IList(Of String) = Nothing
       For Each propMap In tableInfo.PropertyMappings.OfType(Of ScalarPropertyMapping)()
          Dim clrProp = clrType.GetProperty(propMap.Property.Name)
          If Attribute.GetCustomAttribute(clrProp, GetType(UniqueAttribute)) IsNot Nothing Then
             If uniqueCols Is Nothing Then uniqueCols = New List(Of String)
             uniqueCols.Add(propMap.Column.Name)
          End If
       Next
       For Each navProp In setType.NavigationProperties
          Dim clrProp = clrType.GetProperty(navProp.Name)
          If Attribute.GetCustomAttribute(clrProp, GetType(UniqueAttribute)) IsNot Nothing Then
             Dim assocMap = associations.SingleOrDefault(Function(a) _
                a.AssociationSet.ElementType.FullName = navProp.RelationshipType.FullName)
             Dim sProp = assocMap.Conditions.Single
             If uniqueCols Is Nothing Then uniqueCols = New List(Of String)
             uniqueCols.Add(sProp.Column.Name)
          End If
       Next
       If uniqueCols IsNot Nothing Then
          Dim propList = uniqueCols.ToArray()
          context.Database.ExecuteSqlCommand("CREATE UNIQUE INDEX IX_" & tableName & "_" & String.Join("_", propList) _
             & " ON " & schema & "." & tableName & "(" & String.Join(",", propList) & ")")
       End If
    Next
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-08
      • 1970-01-01
      • 2017-09-20
      • 1970-01-01
      • 2010-10-14
      • 1970-01-01
      • 2012-01-09
      相关资源
      最近更新 更多