【问题标题】:EF4: Get the linked column names from NavigationProperty of an EDMXEF4:从 EDMX 的 NavigationProperty 获取链接的列名称
【发布时间】:2011-07-18 22:51:59
【问题描述】:

我正在使用 EDMX 文件中的 T4 模板生成 POCO(假设它们是 MyEntityObject 的子类)。

我有 3 个实体,例如:

  • MyTable1(主键:MyTable1ID)
  • MyTable2(主键:MyTable2ID)
  • MyTable3(主键:MyTable3ID)

这些实体具有以下关系:

MyTable1.MyTable1ID MyTable2.MyTable1ID(MyTable1ID 是 MyTable1) 的外键

MyTable2.MyTable2ID MyTable3.MyTable2ID(MyTable2ID 是 MyTable2 的外键)

或者换一种说法:

我的表 1

我要提取所有外键关系

NavigationProperty[] foreignKeys = entity.NavigationProperties.Where(np => np.DeclaringType == entity && ((AssociationType)np.RelationshipType).IsForeignKey).ToArray();
forewach (NavigationProperty foreignKey in foreignKeys)
{
    // generate code....
}

我的问题:如何提取两个实体之间链接的列名?

类似这样的:

void GetLinkedColumns(MyEntityObject table1, MyEntityObject table2, out string fkColumnTable1, out string fkColumnTable2)
{
    // do the job
}

在示例中

string myTable1Column;
string myTable2Column;
GetLinkedColumns(myTable1, myTable2, out myTable1Column, out myTable2Column);

结果应该是

myTable1Column = "MyTable1ID";
myTable2Column = "MyTable2ID";

【问题讨论】:

    标签: templates entity-framework-4 foreign-keys t4 edmx


    【解决方案1】:

    如果您的外键列在概念模型中作为属性公开,则第一个答案有效。此外,GetSourceSchemaTypes() 方法仅在 EF 附带的部分文本模板中可用,因此了解此方法的作用很有帮助。

    如果您想始终知道列名,则需要从存储模型中加载 AssociationType,如下所示:

    // Obtain a reference to the navigation property you are interested in
    var navProp = GetNavigationProperty();
    
    // Load the metadata workspace
    MetadataWorkspace metadataWorkspace = null;
    bool allMetadataLoaded =loader.TryLoadAllMetadata(inputFile, out metadataWorkspace);
    
    // Get the association type from the storage model
    var association = metadataWorkspace
        .GetItems<AssociationType>(DataSpace.SSpace)
        .Single(a => a.Name == navProp.RelationshipType.Name)
    
    // Then look at the referential constraints
    var toColumns = String.Join(",", 
        association.ReferentialConstraints.SelectMany(rc => rc.ToProperties));
    var fromColumns = String.Join(",", 
        association.ReferentialConstraints.SelectMany(rc => rc.FromProperties));
    

    在这种情况下,loader 是在 EF.Utility.CS.ttinclude 中定义的 MetadataLoader,而 inputFile 是指定 .edmx 文件名称的标准字符串变量。这些应该已经在您的文本模板中声明。

    【讨论】:

      【解决方案2】:

      不确定您是否要使用列生成代码,但这可能部分有助于回答您的问题(如何提取两个实体之间链接的列名?) ...

      NavigationProperty[] foreignKeys = entity.NavigationProperties
        .Where(np => np.DeclaringType == entity &&
                ((AssociationType)np.RelationshipType).IsForeignKey).ToArray();
      
      foreach (NavigationProperty foreignKey in foreignKeys)
      {
         foreach(var rc in GetSourceSchemaTypes<AssociationType>()
             .Single(x => x.Name == foreignKey.RelationshipType.Name)
             .ReferentialConstraints)
         {
             foreach(var tp in rc.ToProperties)
                 WriteLine(tp.Name);
             foreach(var fp in rc.FromProperties)
                 WriteLine(fp.Name);
         }
      }
      

      【讨论】:

        【解决方案3】:

        此代码在我的 Visual Studio 2012 上运行良好

        <#@ template language="C#" debug="true" hostspecific="true"#>
        <#@ include file="EF.Utility.CS.ttinclude"#>
        <#
        string inputFile = @"DomainModel.edmx";
        
        MetadataLoader loader = new MetadataLoader(this);
        
        EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
        
        foreach (EntityType entity in ItemCollection.GetItems<EntityType>().OrderBy(e => e.Name))
        {
            foreach (NavigationProperty navProperty in entity.NavigationProperties)
            {
                AssociationType association = ItemCollection.GetItems<AssociationType>().Single(a => a.Name == navProperty.RelationshipType.Name);
                string fromEntity = association.ReferentialConstraints[0].FromRole.Name;
                string fromEntityField = association.ReferentialConstraints[0].FromProperties[0].Name;
                string toEntity = association.ReferentialConstraints[0].ToRole.Name;
                string toEntityField = association.ReferentialConstraints[0].ToProperties[0].Name;
            }
        }
        
        #>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-09-10
          • 1970-01-01
          • 1970-01-01
          • 2013-04-20
          • 2016-02-01
          • 1970-01-01
          相关资源
          最近更新 更多