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

9 t4 templates foreign-keys edmx entity-framework-4

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

我有3个实体,例如:

  • MyTable1(PrimaryKey:MyTable1ID)
  • MyTable2(PrimaryKey:MyTable2ID)
  • MyTable3(PrimaryKey:MyTable3ID)

这些实体具有以下关系:

MyTable1.MyTable1ID <=> MyTable2.MyTable1ID(MyTable1ID是MyTable1的外键)

MyTable2.MyTable2ID <=> MyTable3.MyTable2ID(MyTable2ID是MyTable2的外键)

或者在另一种观点中:

MyTable1 <= MyTable2 <= MyTable3

我想提取所有外键关系

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

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

像这样的东西:

void GetLinkedColumns(MyEntityObject table1, MyEntityObject table2, out string fkColumnTable1, out string fkColumnTable2)
{
    // do the job
}
Run Code Online (Sandbox Code Playgroud)

在示例中

string myTable1Column;
string myTable2Column;
GetLinkedColumns(myTable1, myTable2, out myTable1Column, out myTable2Column);
Run Code Online (Sandbox Code Playgroud)

结果应该是

myTable1Column = "MyTable1ID";
myTable2Column = "MyTable2ID";
Run Code Online (Sandbox Code Playgroud)

Jam*_*mas 6

如果外键列作为概念模型中的属性公开,则第一个答案有效.此外,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));
Run Code Online (Sandbox Code Playgroud)

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