Access Association Details of NavigationProperty

99封情书 提交于 2019-12-11 08:46:30

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!