什么T4文件用于通过“从数据库更新模型”从数据库生成EDMX? [英] What T4 file is used to generate an EDMX from database via "Update Model From Database"?

查看:238
本文介绍了什么T4文件用于通过“从数据库更新模型”从数据库生成EDMX?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当使用EF4(edmx)模型时,我们经常需要处理从数据库更新模型。通常,我们需要删除表并让它们从数据库中完全重新生成。

When working with an EF4 (edmx) model, we frequently need to process an "Update Model From Database". Commonly, we need to just delete table(s) and let them fully regenerate from the database.

目前的问题是我们有多个递归关系/属性。默认情况下,从数据库更新模型过程将创建具有对象名称的属性,然后为每个其他关系添加1,2,3,4等。所以如果我有多个表示自己多次的公司表(如母公司和dba公司),目前公司1和公司2的edmx结果。我需要控制它们的命名,而不是手动命名。

The issue at hand is that we have multiple recursive relationships/properties. By default, the "update Model From Database" process creates the property with the object's name and then adds a 1, 2, 3, etc. for each additional relationship. So if I have a table of "companies" where it points to itself multiple times (like parent company and dba company), currently the edmx results in Company1 and Company2. I need to control the naming of them....not manually.

如果我能找到T4文件(或拦截和控制的方法) edmx文件本身,我可以解决这个问题。

If i could find the T4 file (or a way to intercept and control) the generation of the edmx file itself, i could fix this problem.

推荐答案

只是绊倒了这个问题,而寻找别的东西,所以我期待你自己解决了一会儿,我有完全一样的问题。我通过使用EDMX.tt预洗T4模板,在EDMX文件中重命名了这些属性。唯一的皱纹是记住在保存EDM设计器更改之后运行它(并确保EDMX文件已签出并可编辑!)

Just stumbled on this question whilst looking for something else, so I expect you have solved it yourself. A while back I had the exact same issue as you however. The way I got round it was by using an EDMX.tt "prewash" T4 template, which re-named those properties in the EDMX file. The only wrinkle is remembering to run it after saving EDM designer changes (and also ensuring the EDMX file is checked out and editable!)

我认为这是另一个功能,可能需要在更高版本的EF中查看。具有名为Address1,Address2等的导航属性没有帮助。

I think this is another feature that may need to be looked at in later versions of EF. Having navigation properties named Address1, Address2, etc. is not helpful.

将EDMX文件拉入内存并进行解析的基本灵感来自于: http://www.codeproject.com/KB/library/EdmxParsing.aspx

The basic inspiration about pulling the EDMX file into memory and parsing it came from here: http://www.codeproject.com/KB/library/EdmxParsing.aspx

一段长的代码和VB启动但在这里你是:

Bit of a long lump of code and in VB to boot but here you are:


<#@ template language="VB" debug="false" hostspecific="true"#>
<#@ import namespace="<xmlns=\"http://schemas.microsoft.com/ado/2008/09/edm\">" #>
<#@ import namespace="<xmlns:edmx=\"http://schemas.microsoft.com/ado/2008/10/edmx\">" #>
<#@ import namespace="System.Xml" #>
<#@ import namespace="System.Xml.Linq" #>
'EDMX pre wash template
'Last run:<#= GetDate() #>
<#
  Main()
#>
<#+
  '----------------------------------------------------------------------------------------------------------
  ' Main
  '----------------------------------------------------------------------------------------------------------
  ''' 
  '''  Parses the EDMX file and renames all navigation properties which are not collections and do not
  '''  reference types by primary key with a their FK name, e.g. navigation property for DefaultAddress_FK is
  '''  renamed to DefaultAddress
  ''' 
  Public Sub Main()

    Dim strPath As String = System.IO.Path.GetDirectoryName(Host.TemplateFile) & "\MyDataModel.edmx"
    Dim edmx As XElement = XElement.Load(strPath)
    Dim itemCol As EdmItemCollection = ReadEdmItemCollection(edmx)
    Dim entity As EntityType
    Dim entityTo As EntityType
    Dim navigationProperties As IEnumerable(Of NavigationProperty)
    Dim navigationProperty As NavigationProperty
    Dim updatableProperty As XElement
    Dim assType As AssociationType
    Dim rc As ReferentialConstraint
    Dim strPropertyName As String
    Dim bModifyProperty As Boolean = False

    For Each entity In itemCol.GetItems(Of EntityType)().OrderBy(Function(e) e.Name)

      navigationProperties = From n In entity.NavigationProperties
                             Where n.DeclaringType Is entity AndAlso
                                   n.ToEndMember.RelationshipMultiplicity  RelationshipMultiplicity.Many

      If navigationProperties.Any() Then
        For Each navigationProperty In navigationProperties
          bModifyProperty = False
          ' Get the association for this navigation property
          assType = (From ass As AssociationType In itemCol.GetItems(Of AssociationType)() _
                     Where ass.AssociationEndMembers IsNot Nothing _
                        AndAlso ass.Name = navigationProperty.RelationshipType.Name _
                     Select ass).AsQueryable().FirstOrDefault()
          If (assType IsNot Nothing) Then

            rc = assType.ReferentialConstraints.FirstOrDefault()
            If (rc IsNot Nothing AndAlso rc.ToProperties.Any) Then
              strPropertyName = rc.ToProperties.First.Name
              ' Make sure the FK is not also a PK on the entity referenced
              entityTo = (From e In itemCol.GetItems(Of EntityType)() Where e.Name = rc.ToRole.Name).FirstOrDefault()
              If (entityTo IsNot Nothing AndAlso
                  Not (From km In entityTo.KeyMembers() Where km.Name = strPropertyName).Any) Then
                ' Get the new name of the property - this uses a little extension
                ' method I wrote to Trim characters at the end of a string matching a regex
                strPropertyName = strPropertyName.TrimEnd("_FK[0-9]{0,1}", options:=0)
                ' Ensure there are no already existant properties with that name on the entity
                If (Not (From p In entity.Properties Where p IsNot navigationProperty AndAlso p.Name = strPropertyName).Any) Then
                  bModifyProperty = True
                End If
              End If

              If (bModifyProperty) Then
                updatableProperty = (From n In (From e In edmx...
                                                Where e.@Name = entity.Name).
                                     Where n.@Name = navigationProperty.Name).FirstOrDefault
                If (updatableProperty IsNot Nothing AndAlso updatableProperty.@Name  strPropertyName) Then
#>'Renaming navigation property on <#= entity.Name #> from <#= updatableProperty.@Name #> to <#= strPropertyName #> in EDMX file
<#+
                  updatableProperty.@Name = strPropertyName
                End If
              End If
            End If

          End If
        Next
      End If

    Next entity

    edmx.Save(strPath)

  End Sub

  '----------------------------------------------------------------------------------------------------------
  ' ReadEdmItemCollection
  '----------------------------------------------------------------------------------------------------------
  ''' 
  '''  Code to parse the EDMX xml document and return the managed EdmItemCollection class
  ''' 
  ''' Taken from here: http://www.codeproject.com/KB/library/EdmxParsing.aspx 
  Public Shared Function ReadEdmItemCollection(edmx As XElement) As EdmItemCollection

    Dim csdlNodes As IEnumerable(Of XElement) = edmx....First.Elements
    Dim readers As IEnumerable(Of XMLReader) = From c As XElement In csdlNodes Select c.CreateReader()
    Return New EdmItemCollection(readers)

  End Function
#>

这篇关于什么T4文件用于通过“从数据库更新模型”从数据库生成EDMX?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆