问题
I'm creating a C# T4 template to scaffold some classes based on .edmx file, so far so good. What I now need though, is a way to access the name of the columns it connects in the database, through a NavigationProperty.
I realized, not long ago, that you can access this information in the .edmx visual designer, under mapping details for an specific NavigationProperty:
So basically, if in the T4 template; I already have an instance of the NavigationProperty I want... How can I get the names of the fields it connects? (WeatherOnMondays
in this case)
回答1:
Answers from: EF4: Get the linked column names from NavigationProperty of an EDMX
2 ways of achieving this:
// 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));
2nd approach:
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);
}
}
回答2:
If you have a NavigationProperty
, the fields it connects are represented by the properties ToEndMember
and FromEndMember
回答3:
This code is simpler. It works fine on my Visual Studio 2012. The AssociationType class details can be found at http://msdn.microsoft.com/en-us/library/system.data.metadata.edm.associationtype.aspx and http://msdn.microsoft.com/en-us/library/system.data.metadata.edm.referentialconstraint.aspx .
<#@ 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;
}
}
#>
回答4:
See http://brewdawg.github.io/Tiraggo.Edmx/ and you can install it from NuGet. It serves up ALL of the metadata in your edmx files, including all the mappings, low level SQL data types per column, all that kind of stuff, look at the sample on the page and you'll see how easy it is.
来源:https://stackoverflow.com/questions/11695412/access-association-details-of-navigationproperty