private static bool IsAssociatedWithEntityType(this AssociationType association, EntityType entityType) { var end1 = association.GetEnd1(); AssociationEndMember end2 = association.GetEnd2(); return(end1.GetEntityType() == entityType || end2.GetEntityType() == entityType); }
internal static XElement ConstructReferentialConstraint( string principalRole, AssociationEndMember principalEnd, string dependentRole, AssociationEndMember dependentEnd) { var refConstraintElement = new XElement(_ssdl + "ReferentialConstraint"); if (dependentEnd != null && principalEnd != null) { var dependentEntityType = dependentEnd.GetEntityType(); var principalEntityType = principalEnd.GetEntityType(); if (dependentEntityType != null && principalEntityType != null) { refConstraintElement = ConstructReferentialConstraintInternal( principalRole, principalEntityType.GetKeyProperties().Select(k => k.Name), dependentRole, principalEntityType.GetKeyProperties().Select( k => OutputGeneratorHelpers.GetFkName( dependentEnd.DeclaringType as AssociationType, dependentEnd, k.Name))); } } return(refConstraintElement); }
/// <inheritdoc/> protected override bool MatchDependentKeyProperty( AssociationType associationType, AssociationEndMember dependentAssociationEnd, EdmProperty dependentProperty, EntityType principalEntityType, EdmProperty principalKeyProperty) { Check.NotNull(associationType, "associationType"); Check.NotNull(dependentAssociationEnd, "dependentAssociationEnd"); Check.NotNull(dependentProperty, "dependentProperty"); Check.NotNull(principalEntityType, "principalEntityType"); Check.NotNull(principalKeyProperty, "principalKeyProperty"); var otherEnd = associationType.GetOtherEnd(dependentAssociationEnd); var navigationProperty = dependentAssociationEnd.GetEntityType().NavigationProperties .SingleOrDefault(n => n.ResultEnd == otherEnd); if (navigationProperty == null) { return(false); } return(string.Equals( dependentProperty.Name, navigationProperty.Name + principalKeyProperty.Name, StringComparison.OrdinalIgnoreCase)); }
// <summary> // 1. If there is a NavigationProperty on the dependent end, then the FK name will be: [NavProp Name]_[Property Name] // 2. If there isn't a NavigationProperty, then we will use the [Association Name]_[EndName]_[Property Name] // </summary> internal static string GetFkName(AssociationType association, AssociationEndMember endWithNavProp, string keyPropertyName) { var fkName = String.Empty; // We attempt to find a navigation property that uses the same association and points to the other end. That last // part is important with self-associations. var principalEnd = association.GetOtherEnd(endWithNavProp); var navigationProperty = endWithNavProp .GetEntityType() .NavigationProperties .Where(np => (np.RelationshipType == association && np.ToEndMember == principalEnd)).FirstOrDefault(); if (navigationProperty != null) { // First attempt to find the NavigationProperty that points to the principal end fkName = String.Format(CultureInfo.CurrentCulture, "{0}_{1}", navigationProperty.Name, keyPropertyName); } else if (association != null) { // If there isn't a NavigationProperty defined, then we will use the Association Name fkName = String.Format(CultureInfo.CurrentCulture, "{0}_{1}_{2}", association.Name, endWithNavProp.Name, keyPropertyName); } Debug.Assert(!String.IsNullOrEmpty(fkName), "Foreign key name could not be determined for the association " + association.Name); //fkName = GetTablePrefix(association.GetEnd1().GetEntityType().NamespaceName) + fkName; return(fkName); }
private static IEnumerable <AssociationType> FindAllOneToOneFKAssociationTypes( EdmModel model, EntityType entityType, EntityType candidateType) { List <AssociationType> associationTypeList = new List <AssociationType>(); foreach (EntityContainer container in model.Containers) { ReadOnlyMetadataCollection <AssociationSet> associationSets = container.AssociationSets; for (int index = 0; index < associationSets.Count; ++index) { AssociationSet associationSet = associationSets[index]; AssociationEndMember sourceEnd = associationSet.ElementType.SourceEnd; AssociationEndMember targetEnd = associationSet.ElementType.TargetEnd; EntityType entityType1 = sourceEnd.GetEntityType(); EntityType entityType2 = targetEnd.GetEntityType(); if (associationSet.ElementType.Constraint != null && sourceEnd.RelationshipMultiplicity == RelationshipMultiplicity.One && targetEnd.RelationshipMultiplicity == RelationshipMultiplicity.One && (entityType1 == entityType && entityType2 == candidateType || entityType2 == entityType && entityType1 == candidateType)) { associationTypeList.Add(associationSet.ElementType); } } } return((IEnumerable <AssociationType>)associationTypeList); }
public static IEnumerable <EdmProperty> GetKeyProperties(this AssociationEndMember end) { IEnumerable <EdmProperty> keyProperties = new List <EdmProperty>(); var entityType = end.GetEntityType(); if (entityType != null) { keyProperties = entityType.GetKeyProperties(); } return(keyProperties); }
// TODO: in order to properly identify this we may need to add custom annotations in the SSDL /// <summary> /// We can infer that something is a join table in the SSDL if: /// 1. There are two associations originating from it /// 2. The two ends on the table are * /// 3. The other ends on the associations are 1 /// 4. The number of properties in the table is equal to the sum of all the key properties on the other ends of both associations /// 5. All properties in the table are key properties /// </summary> /// <param name="entityType">The EntityType to test.</param> /// <param name="store">The StoreItemCollection containing EntityType.</param> /// <returns>true if the specified EntityType is a join table; otherwise, false.</returns> public static bool IsJoinTable(this EntityType entityType, StoreItemCollection store) { var associations = store.GetAllAssociations().Where(a => a.IsAssociatedWithEntityType(entityType)); if (associations.Count() == 2) { var sumOfAllKeyProperties = 0; var numEndsWithOneMultiplicity = 0; foreach (AssociationType association in associations) { AssociationEndMember end1 = association.GetEnd1(); AssociationEndMember end2 = association.GetEnd2(); if ((end1.GetEntityType() == entityType) && (end1.RelationshipMultiplicity == RelationshipMultiplicity.Many) && (end2.RelationshipMultiplicity == RelationshipMultiplicity.One)) { sumOfAllKeyProperties += end2.GetEntityType().GetKeyProperties().Count(); numEndsWithOneMultiplicity++; } else if ((end2.GetEntityType() == entityType) && (end2.RelationshipMultiplicity == RelationshipMultiplicity.Many) && (end1.RelationshipMultiplicity == RelationshipMultiplicity.One)) { sumOfAllKeyProperties += end1.GetEntityType().GetKeyProperties().Count(); numEndsWithOneMultiplicity++; } } int intersectCount = entityType.GetKeyProperties().Intersect(entityType.Properties).Count(); if (numEndsWithOneMultiplicity == 2 && entityType.GetKeyProperties().Count() == sumOfAllKeyProperties && entityType.GetKeyProperties().Count() == intersectCount && entityType.Properties.Count == intersectCount) { return(true); } } return(false); }
internal void WriteAssociationEndElementHeader(AssociationEndMember associationEnd) { _xmlWriter.WriteStartElement(XmlConstants.End); _xmlWriter.WriteAttributeString(XmlConstants.Role, associationEnd.Name); var typeName = associationEnd.GetEntityType().Name; _xmlWriter.WriteAttributeString( XmlConstants.TypeAttribute, GetQualifiedTypeName(XmlConstants.Self, typeName)); _xmlWriter.WriteAttributeString( XmlConstants.Multiplicity, GetXmlMultiplicity(associationEnd.RelationshipMultiplicity)); }
// <summary> // A name derived from a *:* association will be: FK_[Association Name]_[End Name]. Note that we are // getting the association name for *one* of the SSDL associations that are inferred from a CSDL *:* // association. The 'principalEnd' corresponds to the end of the *:* association that will become // the principal end in the 1:* association (where the * end is the newly-constructed entity corresponding // to the link table) // </summary> internal static string GetStorageAssociationSetNameFromManyToMany(AssociationSet associationSet, AssociationEndMember principalEnd) { Debug.Assert(associationSet != null, "AssociationSet should not be null"); Debug.Assert(principalEnd != null, "The principal end cannot be null"); var associationSetName = String.Empty; if (associationSet != null && principalEnd != null) { associationSetName = String.Format( CultureInfo.CurrentCulture, Resources.CodeViewManyToManyAssocName, OutputGeneratorHelpers.GetTablePrefix(principalEnd.GetEntityType().NamespaceName) + associationSet.Name, principalEnd.Name); } return(associationSetName); }
/// <inheritdoc /> protected override bool MatchDependentKeyProperty( AssociationType associationType, AssociationEndMember dependentAssociationEnd, EdmProperty dependentProperty, EntityType principalEntityType, EdmProperty principalKeyProperty) { Check.NotNull<AssociationType>(associationType, nameof (associationType)); Check.NotNull<AssociationEndMember>(dependentAssociationEnd, nameof (dependentAssociationEnd)); Check.NotNull<EdmProperty>(dependentProperty, nameof (dependentProperty)); Check.NotNull<EntityType>(principalEntityType, nameof (principalEntityType)); Check.NotNull<EdmProperty>(principalKeyProperty, nameof (principalKeyProperty)); AssociationEndMember otherEnd = associationType.GetOtherEnd(dependentAssociationEnd); NavigationProperty navigationProperty = dependentAssociationEnd.GetEntityType().NavigationProperties.SingleOrDefault<NavigationProperty>((Func<NavigationProperty, bool>) (n => n.ResultEnd == otherEnd)); if (navigationProperty == null) return false; return string.Equals(dependentProperty.Name, navigationProperty.Name + principalKeyProperty.Name, StringComparison.OrdinalIgnoreCase); }
// <summary> // A name derived from a *:* association will be: FK_[Association Name]_[End Name]. Note that we are // getting the association name for *one* of the SSDL associations that are inferred from a CSDL *:* // association. The 'principalEnd' corresponds to the end of the *:* association that will become // the principal end in the 1:* association (where the * end is the newly-constructed entity corresponding // to the link table) // </summary> internal static string GetStorageAssociationNameFromManyToMany(AssociationEndMember principalEnd) { var association = principalEnd.DeclaringType as AssociationType; Debug.Assert( association != null, "The DeclaringType of the AssociationEndMember " + principalEnd.Name + " should be an AssociationType"); Debug.Assert(principalEnd != null, "The principal end cannot be null"); var associationName = String.Empty; if (association != null && principalEnd != null) { associationName = String.Format( CultureInfo.CurrentCulture, Resources.CodeViewManyToManyAssocName, OutputGeneratorHelpers.GetTablePrefix(principalEnd.GetEntityType().NamespaceName) + association.Name, principalEnd.Name); } return(associationName); }
/// <inheritdoc /> public virtual void Apply(NavigationProperty item, DbModel model) { Check.NotNull <NavigationProperty>(item, nameof(item)); Check.NotNull <DbModel>(model, nameof(model)); AssociationType association = item.Association; if (association.Constraint != null) { return; } ForeignKeyAttribute foreignKeyAttribute = item.GetClrAttributes <ForeignKeyAttribute>().SingleOrDefault <ForeignKeyAttribute>(); AssociationEndMember principalEnd; AssociationEndMember dependentEnd; if (foreignKeyAttribute == null || !association.TryGuessPrincipalAndDependentEnds(out principalEnd, out dependentEnd) && !association.IsPrincipalConfigured()) { return; } AssociationEndMember associationEndMember = dependentEnd ?? association.TargetEnd; principalEnd = principalEnd ?? association.SourceEnd; IEnumerable <string> dependentPropertyNames = ((IEnumerable <string>)foreignKeyAttribute.Name.Split(',')).Select <string, string>((Func <string, string>)(p => p.Trim())); EntityType declaringEntityType = model.ConceptualModel.EntityTypes.Single <EntityType>((Func <EntityType, bool>)(e => e.DeclaredNavigationProperties.Contains(item))); List <EdmProperty> list = ForeignKeyNavigationPropertyAttributeConvention.GetDependentProperties(associationEndMember.GetEntityType(), dependentPropertyNames, declaringEntityType, item).ToList <EdmProperty>(); ReferentialConstraint constraint = new ReferentialConstraint((RelationshipEndMember)principalEnd, (RelationshipEndMember)associationEndMember, (IEnumerable <EdmProperty>)principalEnd.GetEntityType().KeyProperties().ToList <EdmProperty>(), (IEnumerable <EdmProperty>)list); IEnumerable <EdmProperty> source = associationEndMember.GetEntityType().KeyProperties(); if (source.Count <EdmProperty>() == constraint.ToProperties.Count <EdmProperty>() && source.All <EdmProperty>((Func <EdmProperty, bool>)(kp => constraint.ToProperties.Contains(kp)))) { principalEnd.RelationshipMultiplicity = RelationshipMultiplicity.One; if (associationEndMember.RelationshipMultiplicity.IsMany()) { associationEndMember.RelationshipMultiplicity = RelationshipMultiplicity.ZeroOrOne; } } if (principalEnd.IsRequired()) { constraint.ToProperties.Each <EdmProperty, bool>((Func <EdmProperty, bool>)(p => p.Nullable = false)); } association.Constraint = constraint; }
internal override void Configure( AssociationType associationType, AssociationEndMember dependentEnd, EntityTypeConfiguration entityTypeConfiguration) { DebugCheck.NotNull(associationType); DebugCheck.NotNull(dependentEnd); DebugCheck.NotNull(entityTypeConfiguration); if (!_dependentProperties.Any()) { return; } var dependentPropertInfos = _dependentProperties.AsEnumerable(); if (!IsFullySpecified) { var foreignKeys = from p in _dependentProperties select new { PropertyInfo = p, entityTypeConfiguration.Property(new PropertyPath(p)).ColumnOrder }; if ((_dependentProperties.Count > 1) && foreignKeys.Any(p => !p.ColumnOrder.HasValue)) { var dependentKeys = dependentEnd.GetEntityType().KeyProperties; if ((dependentKeys.Count == _dependentProperties.Count) && foreignKeys.All(fk => dependentKeys.Any(p => p.GetClrPropertyInfo().IsSameAs(fk.PropertyInfo)))) { // The FK and PK sets are equal, we know the order dependentPropertInfos = dependentKeys.Select(p => p.GetClrPropertyInfo()); } else { throw Error.ForeignKeyAttributeConvention_OrderRequired(entityTypeConfiguration.ClrType); } } else { dependentPropertInfos = foreignKeys.OrderBy(p => p.ColumnOrder).Select(p => p.PropertyInfo); } } var dependentProperties = new List <EdmProperty>(); foreach (var dependentProperty in dependentPropertInfos) { var property = dependentEnd.GetEntityType() .GetDeclaredPrimitiveProperty(dependentProperty); if (property == null) { throw Error.ForeignKeyPropertyNotFound( dependentProperty.Name, dependentEnd.GetEntityType().Name); } dependentProperties.Add(property); } var principalEnd = associationType.GetOtherEnd(dependentEnd); var associationConstraint = new ReferentialConstraint( principalEnd, dependentEnd, principalEnd.GetEntityType().KeyProperties, dependentProperties); if (principalEnd.IsRequired()) { associationConstraint.ToProperties.Each(p => p.Nullable = false); } associationType.Constraint = associationConstraint; }
/// <inheritdoc /> public virtual void Apply(AssociationType item, DbModel model) { Check.NotNull <AssociationType>(item, nameof(item)); Check.NotNull <DbModel>(model, nameof(model)); if (!item.IsOneToOne() || item.IsSelfReferencing() || (item.IsIndependent() || item.Constraint != null)) { return; } IEnumerable <EdmProperty> source1 = item.SourceEnd.GetEntityType().KeyProperties(); IEnumerable <EdmProperty> source2 = item.TargetEnd.GetEntityType().KeyProperties(); AssociationEndMember principalEnd; AssociationEndMember dependentEnd; if (source1.Count <EdmProperty>() != source2.Count <EdmProperty>() || (!source1.Select <EdmProperty, PrimitiveType>((Func <EdmProperty, PrimitiveType>)(p => p.UnderlyingPrimitiveType)).SequenceEqual <PrimitiveType>(source2.Select <EdmProperty, PrimitiveType>((Func <EdmProperty, PrimitiveType>)(p => p.UnderlyingPrimitiveType))) || !item.TryGuessPrincipalAndDependentEnds(out principalEnd, out dependentEnd) && !item.IsPrincipalConfigured())) { return; } AssociationEndMember associationEnd = dependentEnd ?? item.TargetEnd; AssociationEndMember otherEnd = item.GetOtherEnd(associationEnd); ReferentialConstraint referentialConstraint = new ReferentialConstraint((RelationshipEndMember)otherEnd, (RelationshipEndMember)associationEnd, (IEnumerable <EdmProperty>)otherEnd.GetEntityType().KeyProperties().ToList <EdmProperty>(), (IEnumerable <EdmProperty>)associationEnd.GetEntityType().KeyProperties().ToList <EdmProperty>()); item.Constraint = referentialConstraint; }
private static NavigationProperty GetNavigationProperty(AssociationEndMember member) { return(member.GetEntityType().NavigationProperties.SingleOrDefault(property => property.RelationshipType == member.DeclaringType && property.FromEndMember == member)); }
private List <ModelBidirectionalAssociation> GetBidirectionalAssociations(EntityType entityType) { List <ModelBidirectionalAssociation> result = new List <ModelBidirectionalAssociation>(); if (entityType == null) { return(result); } foreach (NavigationProperty navigationProperty in entityType.DeclaredNavigationProperties.Where(np => Inverse(np) != null)) { StructuralType sourceType = navigationProperty.DeclaringType; if (sourceType.Name != entityType.Name) { continue; } ModelBidirectionalAssociation association = new ModelBidirectionalAssociation(); EntityType targetType = navigationProperty.ToEndMember.GetEntityType(); AssociationType associationType = navigationProperty.RelationshipType as AssociationType; ReferentialConstraint constraint = associationType?.Constraint; AssociationEndMember principalEnd = constraint?.FromRole as AssociationEndMember; EntityType principalType = principalEnd?.GetEntityType(); AssociationEndMember dependentEnd = constraint?.ToRole as AssociationEndMember; EntityType dependentType = dependentEnd?.GetEntityType(); if (principalType?.Name == sourceType.Name) { association.SourceRole = AssociationRole.Principal; association.TargetRole = AssociationRole.Dependent; } else if (principalType?.Name == targetType.Name) { association.TargetRole = AssociationRole.Principal; association.SourceRole = AssociationRole.Dependent; } else if (principalType == null && dependentType == null) { association.SourceRole = AssociationRole.NotApplicable; association.TargetRole = AssociationRole.NotApplicable; } association.SourceClassName = sourceType.Name; association.SourceClassNamespace = sourceType.NamespaceName; association.TargetClassName = targetType.Name; association.TargetClassNamespace = targetType.NamespaceName; NavigationProperty inverse = Inverse(navigationProperty); // the property in the source class (referencing the target class) association.TargetPropertyTypeName = targetType.Name; association.TargetPropertyName = navigationProperty.Name; association.TargetMultiplicity = ConvertMultiplicity(navigationProperty.ToEndMember.RelationshipMultiplicity); association.TargetSummary = navigationProperty.ToEndMember.Documentation?.Summary; association.TargetDescription = navigationProperty.ToEndMember.Documentation?.LongDescription; // the property in the target class (referencing the source class) association.SourcePropertyTypeName = navigationProperty.FromEndMember.GetEntityType().Name; association.SourcePropertyName = inverse?.Name; association.SourceMultiplicity = ConvertMultiplicity(navigationProperty.FromEndMember.RelationshipMultiplicity); association.SourceSummary = navigationProperty.FromEndMember.Documentation?.Summary; association.SourceDescription = navigationProperty.FromEndMember.Documentation?.LongDescription; // look for declared foreign keys List <EdmProperty> dependentProperties = navigationProperty.GetDependentProperties().ToList(); if (dependentProperties.Any()) { association.ForeignKey = string.Join(",", dependentProperties.Select(p => p.Name)); } log.Debug($"Found bidirectional association {association.SourceClassName}.{association.TargetPropertyName} <-> {association.TargetClassName}.{association.SourcePropertyTypeName}"); log.Debug("\n " + JsonConvert.SerializeObject(association)); result.Add(association); } return(result); }
internal override void Configure( AssociationType associationType, AssociationEndMember dependentEnd, EntityTypeConfiguration entityTypeConfiguration) { // ISSUE: object of a compiler-generated type is created // ISSUE: variable of a compiler-generated type ForeignKeyConstraintConfiguration.\u003C\u003Ec__DisplayClasse cDisplayClasse1 = new ForeignKeyConstraintConfiguration.\u003C\u003Ec__DisplayClasse(); // ISSUE: reference to a compiler-generated field cDisplayClasse1.entityTypeConfiguration = entityTypeConfiguration; if (!this._dependentProperties.Any <PropertyInfo>()) { return; } IEnumerable <PropertyInfo> propertyInfos = this._dependentProperties.AsEnumerable <PropertyInfo>(); if (!this.IsFullySpecified) { // ISSUE: reference to a compiler-generated field if (EntityTypeExtensions.GetClrType(dependentEnd.GetEntityType()) != cDisplayClasse1.entityTypeConfiguration.ClrType) { return; } // ISSUE: reference to a compiler-generated method IEnumerable <\u003C\u003Ef__AnonymousType41 <PropertyInfo, int?> > source = this._dependentProperties.Select(new Func <PropertyInfo, \u003C\u003Ef__AnonymousType41 <PropertyInfo, int?> >(cDisplayClasse1.\u003CConfigure\u003Eb__0)); if (this._dependentProperties.Count > 1 && source.Any(p => !p.ColumnOrder.HasValue)) { ReadOnlyMetadataCollection <EdmProperty> dependentKeys = dependentEnd.GetEntityType().KeyProperties; if (dependentKeys.Count != this._dependentProperties.Count || !source.All(fk => { // ISSUE: variable of a compiler-generated type ForeignKeyConstraintConfiguration.\u003C\u003Ec__DisplayClasse cDisplayClasse = cDisplayClasse1; var fk1 = fk; return(dependentKeys.Any <EdmProperty>((Func <EdmProperty, bool>)(p => p.GetClrPropertyInfo().IsSameAs(fk1.PropertyInfo)))); })) { // ISSUE: reference to a compiler-generated field throw Error.ForeignKeyAttributeConvention_OrderRequired((object)cDisplayClasse1.entityTypeConfiguration.ClrType); } propertyInfos = dependentKeys.Select <EdmProperty, PropertyInfo>((Func <EdmProperty, PropertyInfo>)(p => p.GetClrPropertyInfo())); } else { propertyInfos = source.OrderBy(p => p.ColumnOrder).Select(p => p.PropertyInfo); } } List <EdmProperty> edmPropertyList = new List <EdmProperty>(); foreach (PropertyInfo propertyInfo in propertyInfos) { EdmProperty primitiveProperty = dependentEnd.GetEntityType().GetDeclaredPrimitiveProperty(propertyInfo); if (primitiveProperty == null) { throw Error.ForeignKeyPropertyNotFound((object)propertyInfo.Name, (object)dependentEnd.GetEntityType().Name); } edmPropertyList.Add(primitiveProperty); } AssociationEndMember otherEnd = associationType.GetOtherEnd(dependentEnd); ReferentialConstraint referentialConstraint = new ReferentialConstraint((RelationshipEndMember)otherEnd, (RelationshipEndMember)dependentEnd, (IEnumerable <EdmProperty>)otherEnd.GetEntityType().KeyProperties, (IEnumerable <EdmProperty>)edmPropertyList); if (otherEnd.IsRequired()) { referentialConstraint.ToProperties.Each <EdmProperty, bool>((Func <EdmProperty, bool>)(p => p.Nullable = false)); } associationType.Constraint = referentialConstraint; }
private static void GenerateForeignKeyAssociationType( AssociationType associationType, DbDatabaseMapping databaseMapping) { AssociationEndMember dependentEnd = associationType.Constraint.DependentEnd; AssociationEndMember otherEnd = associationType.GetOtherEnd(dependentEnd); EntityTypeMapping mappingInHierarchy = StructuralTypeMappingGenerator.GetEntityTypeMappingInHierarchy(databaseMapping, otherEnd.GetEntityType()); EntityTypeMapping dependentEntityTypeMapping = StructuralTypeMappingGenerator.GetEntityTypeMappingInHierarchy(databaseMapping, dependentEnd.GetEntityType()); ForeignKeyBuilder foreignKeyBuilder = new ForeignKeyBuilder(databaseMapping.Database, associationType.Name) { PrincipalTable = mappingInHierarchy.MappingFragments.Single <MappingFragment>().Table, DeleteAction = otherEnd.DeleteBehavior != OperationAction.None ? otherEnd.DeleteBehavior : OperationAction.None }; dependentEntityTypeMapping.MappingFragments.Single <MappingFragment>().Table.AddForeignKey(foreignKeyBuilder); foreignKeyBuilder.DependentColumns = associationType.Constraint.ToProperties.Select <EdmProperty, EdmProperty>((Func <EdmProperty, EdmProperty>)(dependentProperty => dependentEntityTypeMapping.GetPropertyMapping(dependentProperty).ColumnProperty)); foreignKeyBuilder.SetAssociationType(associationType); }