Templates EF4:从EDMX的NavigationProperty获取链接的列名

Templates EF4:从EDMX的NavigationProperty获取链接的列名,templates,entity-framework-4,foreign-keys,t4,edmx,Templates,Entity Framework 4,Foreign Keys,T4,Edmx,我使用来自EDMX文件的T4模板生成POCO(假设它们是MyEntityObject的子类) 我有3个实体,例如: MyTable1(主键:MyTable1ID) MyTable2(主键:MyTable2ID) MyTable3(主键:MyTable3ID) 这些实体具有以下关系: MyTable1.MyTable1ID MyTable2.MyTable1ID(MyTable1ID是 MyTable1的外键 MyTable2.MyTable2ID MyTable3.MyTable2ID(My

我使用来自EDMX文件的T4模板生成POCO(假设它们是MyEntityObject的子类)

我有3个实体,例如:

  • MyTable1(主键:MyTable1ID)
  • MyTable2(主键:MyTable2ID)
  • MyTable3(主键:MyTable3ID)
这些实体具有以下关系:

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

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

或者从另一个角度来看:


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

NavigationProperty[]foreignKeys=entity.NavigationProperties
.其中(np=>np.DeclaringType==实体&&
((AssociationType)np.RelationshipType).IsForeignKey.ToArray();
foreach(foreignKey中的NavigationProperty foreignKey)
{
foreach(GetSourceSchemaTypes()中的var rc)
.Single(x=>x.Name==foreignKey.RelationshipType.Name)
.参考约束)
{
foreach(rc.TopProperty中的var tp)
WriteLine(总称);
foreach(rc.FromProperties中的变量fp)
WriteLine(fp.Name);
}
}

如果外键列在概念模型中作为属性公开,则第一个答案有效。此外,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));
//获取对您感兴趣的导航属性的引用
var navProp=GetNavigationProperty();
//加载元数据工作区
MetadataWorkspace MetadataWorkspace=null;
bool allMetadataLoaded=loader.TryLoadAllMetadata(inputFile,OutMetadataWorkspace);
//从存储模型中获取关联类型
var关联=metadataWorkspace
.GetItems(DataSpace.SSpace)
.Single(a=>a.Name==navProp.RelationshipType.Name)
//然后看看引用约束
var toColumns=String.Join(“,”,
SelectMany(rc=>rc.ToProperties));
var fromColumns=String.Join(“,”,
SelectMany(rc=>rc.FromProperties));

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

此代码在my 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;
    }
}

#>

e、 (姓名)
{
foreach(实体中的NavigationProperty navProperty.NavigationProperties)
{
AssociationType association=ItemCollection.GetItems().Single(a=>a.Name==navProperty.RelationshipType.Name);
string fromEntity=association.ReferentialConstraints[0]。FromRole.Name;
字符串fromEntityField=association.ReferentialConstraints[0]。FromProperties[0]。名称;
string toEntity=association.ReferentialConstraints[0].ToRole.Name;
string toEntityField=association.ReferentialConstraints[0]。TopProperties[0]。名称;
}
}
#>
string myTable1Column;
string myTable2Column;
GetLinkedColumns(myTable1, myTable2, out myTable1Column, out myTable2Column);
myTable1Column = "MyTable1ID";
myTable2Column = "MyTable2ID";
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);
   }
}
// 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));
<#@ 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;
    }
}

#>