private void ConfigureDependentBehavior( AssociationType associationType, EdmModel model, EntityTypeConfiguration entityTypeConfiguration) { DebugCheck.NotNull(associationType); DebugCheck.NotNull(model); DebugCheck.NotNull(entityTypeConfiguration); AssociationEndMember principalEnd; AssociationEndMember dependentEnd; if (!associationType.TryGuessPrincipalAndDependentEnds(out principalEnd, out dependentEnd)) { if (IsNavigationPropertyDeclaringTypePrincipal.HasValue) { associationType.MarkPrincipalConfigured(); var navProp = model.EntityTypes .SelectMany(et => et.DeclaredNavigationProperties) .Single( np => np.RelationshipType.Equals(associationType) && // CodePlex 546 np.GetClrPropertyInfo().IsSameAs(NavigationProperty)); principalEnd = IsNavigationPropertyDeclaringTypePrincipal.Value ? associationType.GetOtherEnd(navProp.ResultEnd) : navProp.ResultEnd; dependentEnd = associationType.GetOtherEnd(principalEnd); if (associationType.SourceEnd != principalEnd) { // need to move around source to be principal, target to be dependent so Edm services will use the correct // principal and dependent ends. The Edm default Db + mapping service tries to guess principal/dependent // based on multiplicities, but if it can't figure it out, it will use source as principal and target as dependent associationType.SourceEnd = principalEnd; associationType.TargetEnd = dependentEnd; var associationSet = model.Containers .SelectMany(ct => ct.AssociationSets) .Single(aset => aset.ElementType == associationType); var sourceSet = associationSet.SourceSet; associationSet.SourceSet = associationSet.TargetSet; associationSet.TargetSet = sourceSet; } } if (principalEnd == null) { dependentEnd = associationType.TargetEnd; } } ConfigureConstraint(associationType, dependentEnd, entityTypeConfiguration); ConfigureDeleteAction(associationType.GetOtherEnd(dependentEnd)); }
public void GetOtherEnd_should_return_correct_end() { var associationType = new AssociationType(); associationType.SourceEnd = new AssociationEndMember("S", new EntityType()); associationType.TargetEnd = new AssociationEndMember("T", new EntityType()); Assert.Same(associationType.SourceEnd, associationType.GetOtherEnd(associationType.TargetEnd)); Assert.Same(associationType.TargetEnd, associationType.GetOtherEnd(associationType.SourceEnd)); }
public void GetOtherEnd_should_return_correct_end() { var associationType = new AssociationType("A", XmlConstants.ModelNamespace_3, false, DataSpace.CSpace); associationType.SourceEnd = new AssociationEndMember("S", new EntityType("E", "N", DataSpace.CSpace)); associationType.TargetEnd = new AssociationEndMember("T", new EntityType("E", "N", DataSpace.CSpace)); Assert.Same(associationType.SourceEnd, associationType.GetOtherEnd(associationType.TargetEnd)); Assert.Same(associationType.TargetEnd, associationType.GetOtherEnd(associationType.SourceEnd)); }
/// <inheritdoc /> public virtual void Apply(AssociationType item, DbModel model) { Check.NotNull <AssociationType>(item, nameof(item)); Check.NotNull <DbModel>(model, nameof(model)); if (item.Constraint == null) { return; } IEnumerable <EdmProperty> source = item.GetOtherEnd(item.Constraint.DependentEnd).GetEntityType().KeyProperties(); if (source.Count <EdmProperty>() != item.Constraint.ToProperties.Count) { return; } for (int index = 0; index < item.Constraint.ToProperties.Count; ++index) { EdmProperty toProperty = item.Constraint.ToProperties[index]; EdmProperty edmProperty = source.ElementAt <EdmProperty>(index); if (toProperty.PrimitiveType == PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String) || toProperty.PrimitiveType == PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Binary)) { toProperty.IsUnicode = edmProperty.IsUnicode; toProperty.IsFixedLength = edmProperty.IsFixedLength; toProperty.MaxLength = edmProperty.MaxLength; toProperty.IsMaxLength = edmProperty.IsMaxLength; } } }
private static void UpdatePrincipalTables( DbDatabaseMapping databaseMapping, EntityType toTable, bool removeFks, AssociationType associationType, EntityType et) { List <AssociationEndMember> associationEndMemberList = new List <AssociationEndMember>(); AssociationEndMember principalEnd; AssociationEndMember dependentEnd; if (associationType.TryGuessPrincipalAndDependentEnds(out principalEnd, out dependentEnd)) { associationEndMemberList.Add(principalEnd); } else if (associationType.SourceEnd.RelationshipMultiplicity == RelationshipMultiplicity.Many && associationType.TargetEnd.RelationshipMultiplicity == RelationshipMultiplicity.Many) { associationEndMemberList.Add(associationType.SourceEnd); associationEndMemberList.Add(associationType.TargetEnd); } else { associationEndMemberList.Add(associationType.SourceEnd); } foreach (AssociationEndMember associationEnd in associationEndMemberList) { if (associationEnd.GetEntityType() == et) { IEnumerable <KeyValuePair <EntityType, IEnumerable <EdmProperty> > > keyValuePairs; if (associationType.Constraint != null) { EntityType entityType = associationType.GetOtherEnd(associationEnd).GetEntityType(); keyValuePairs = databaseMapping.Model.GetSelfAndAllDerivedTypes(entityType).Select <EntityType, EntityTypeMapping>((Func <EntityType, EntityTypeMapping>)(t => databaseMapping.GetEntityTypeMapping(t))).Where <EntityTypeMapping>((Func <EntityTypeMapping, bool>)(dm => dm != null)).SelectMany <EntityTypeMapping, MappingFragment>((Func <EntityTypeMapping, IEnumerable <MappingFragment> >)(dm => dm.MappingFragments.Where <MappingFragment>((Func <MappingFragment, bool>)(tmf => associationType.Constraint.ToProperties.All <EdmProperty>((Func <EdmProperty, bool>)(p => tmf.ColumnMappings.Any <ColumnMappingBuilder>((Func <ColumnMappingBuilder, bool>)(pm => pm.PropertyPath.First <EdmProperty>() == p)))))))).Distinct <MappingFragment>((Func <MappingFragment, MappingFragment, bool>)((f1, f2) => f1.Table == f2.Table)).Select <MappingFragment, KeyValuePair <EntityType, IEnumerable <EdmProperty> > >((Func <MappingFragment, KeyValuePair <EntityType, IEnumerable <EdmProperty> > >)(df => new KeyValuePair <EntityType, IEnumerable <EdmProperty> >(df.Table, df.ColumnMappings.Where <ColumnMappingBuilder>((Func <ColumnMappingBuilder, bool>)(pm => associationType.Constraint.ToProperties.Contains(pm.PropertyPath.First <EdmProperty>()))).Select <ColumnMappingBuilder, EdmProperty>((Func <ColumnMappingBuilder, EdmProperty>)(pm => pm.ColumnProperty))))); } else { AssociationSetMapping associationSetMapping = databaseMapping.EntityContainerMappings.Single <EntityContainerMapping>().AssociationSetMappings.Single <AssociationSetMapping>((Func <AssociationSetMapping, bool>)(asm => asm.AssociationSet.ElementType == associationType)); keyValuePairs = (IEnumerable <KeyValuePair <EntityType, IEnumerable <EdmProperty> > >) new KeyValuePair <EntityType, IEnumerable <EdmProperty> >[1] { new KeyValuePair <EntityType, IEnumerable <EdmProperty> >(associationSetMapping.Table, (associationSetMapping.SourceEndMapping.AssociationEnd == associationEnd ? (IEnumerable <ScalarPropertyMapping>)associationSetMapping.SourceEndMapping.PropertyMappings : (IEnumerable <ScalarPropertyMapping>)associationSetMapping.TargetEndMapping.PropertyMappings).Select <ScalarPropertyMapping, EdmProperty>((Func <ScalarPropertyMapping, EdmProperty>)(pm => pm.Column))) }; } foreach (KeyValuePair <EntityType, IEnumerable <EdmProperty> > keyValuePair in keyValuePairs) { KeyValuePair <EntityType, IEnumerable <EdmProperty> > tableInfo = keyValuePair; foreach (ForeignKeyBuilder foreignKeyBuilder in tableInfo.Key.ForeignKeyBuilders.Where <ForeignKeyBuilder>((Func <ForeignKeyBuilder, bool>)(fk => fk.DependentColumns.SequenceEqual <EdmProperty>(tableInfo.Value))).ToArray <ForeignKeyBuilder>()) { if (removeFks) { tableInfo.Key.RemoveForeignKey(foreignKeyBuilder); } else if (foreignKeyBuilder.GetAssociationType() == null || foreignKeyBuilder.GetAssociationType() == associationType) { foreignKeyBuilder.PrincipalTable = toTable; } } } } } }
/// <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)); }
private static void GenerateForeignKeyAssociationType( AssociationType associationType, DbDatabaseMapping databaseMapping) { DebugCheck.NotNull(associationType); DebugCheck.NotNull(databaseMapping); Debug.Assert(associationType.Constraint != null); var dependentEnd = associationType.Constraint.DependentEnd; var principalEnd = associationType.GetOtherEnd(dependentEnd); var principalEntityTypeMapping = GetEntityTypeMappingInHierarchy(databaseMapping, principalEnd.GetEntityType()); var dependentEntityTypeMapping = GetEntityTypeMappingInHierarchy(databaseMapping, dependentEnd.GetEntityType()); var foreignKeyConstraint = new ForeignKeyBuilder(databaseMapping.Database, associationType.Name) { PrincipalTable = principalEntityTypeMapping.MappingFragments.Single().Table, DeleteAction = principalEnd.DeleteBehavior != OperationAction.None ? principalEnd.DeleteBehavior : OperationAction.None }; dependentEntityTypeMapping .MappingFragments .Single() .Table .AddForeignKey(foreignKeyConstraint); foreignKeyConstraint.DependentColumns = associationType.Constraint.ToProperties.Select( dependentProperty => dependentEntityTypeMapping.GetPropertyMapping(dependentProperty).ColumnProperty); foreignKeyConstraint.SetAssociationType(associationType); }
// <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); }
/// <summary> /// Retrieves the principal end of this association /// </summary> /// <param name="association">The association.</param> /// <returns>The principal end.</returns> public static AssociationEndMember GetPrincipalEnd(this AssociationType association) { var dependentEnd = association.GetDependentEnd(); if (dependentEnd != null) { return(association.GetOtherEnd(dependentEnd)); } return(null); }
private void ConfigureDependentBehavior( AssociationType associationType, EdmModel model, EntityTypeConfiguration entityTypeConfiguration) { AssociationEndMember principalEnd; AssociationEndMember dependentEnd; if (!associationType.TryGuessPrincipalAndDependentEnds(out principalEnd, out dependentEnd)) { if (this.IsNavigationPropertyDeclaringTypePrincipal.HasValue) { associationType.MarkPrincipalConfigured(); System.Data.Entity.Core.Metadata.Edm.NavigationProperty navigationProperty = model.EntityTypes.SelectMany <EntityType, System.Data.Entity.Core.Metadata.Edm.NavigationProperty>((Func <EntityType, IEnumerable <System.Data.Entity.Core.Metadata.Edm.NavigationProperty> >)(et => (IEnumerable <System.Data.Entity.Core.Metadata.Edm.NavigationProperty>)et.DeclaredNavigationProperties)).Single <System.Data.Entity.Core.Metadata.Edm.NavigationProperty>((Func <System.Data.Entity.Core.Metadata.Edm.NavigationProperty, bool>)(np => { if (np.RelationshipType.Equals((object)associationType)) { return(np.GetClrPropertyInfo().IsSameAs(this.NavigationProperty)); } return(false); })); principalEnd = this.IsNavigationPropertyDeclaringTypePrincipal.Value ? associationType.GetOtherEnd(navigationProperty.ResultEnd) : navigationProperty.ResultEnd; dependentEnd = associationType.GetOtherEnd(principalEnd); if (associationType.SourceEnd != principalEnd) { associationType.SourceEnd = principalEnd; associationType.TargetEnd = dependentEnd; AssociationSet associationSet = model.Containers.SelectMany <EntityContainer, AssociationSet>((Func <EntityContainer, IEnumerable <AssociationSet> >)(ct => (IEnumerable <AssociationSet>)ct.AssociationSets)).Single <AssociationSet>((Func <AssociationSet, bool>)(aset => aset.ElementType == associationType)); EntitySet sourceSet = associationSet.SourceSet; associationSet.SourceSet = associationSet.TargetSet; associationSet.TargetSet = sourceSet; } } if (principalEnd == null) { dependentEnd = associationType.TargetEnd; } } this.ConfigureConstraint(associationType, dependentEnd, entityTypeConfiguration); this.ConfigureDeleteAction(associationType.GetOtherEnd(dependentEnd)); }
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); }
/// <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); }
/// <inheritdoc/> public virtual void Apply(AssociationType item, DbModel model) { Check.NotNull(item, "item"); Check.NotNull(model, "model"); if (item.Constraint == null) { return; } var principalKeyProperties = item .GetOtherEnd(item.Constraint.DependentEnd).GetEntityType() .KeyProperties(); if (principalKeyProperties.Count() != item.Constraint.ToProperties.Count) { return; } for (var i = 0; i < item.Constraint.ToProperties.Count; i++) { var dependentProperty = item.Constraint.ToProperties[i]; var principalProperty = principalKeyProperties.ElementAt(i); if ((dependentProperty.PrimitiveType == PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String)) || (dependentProperty.PrimitiveType == PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Binary))) { dependentProperty.IsUnicode = principalProperty.IsUnicode; dependentProperty.IsFixedLength = principalProperty.IsFixedLength; dependentProperty.MaxLength = principalProperty.MaxLength; dependentProperty.IsMaxLength = principalProperty.IsMaxLength; } } }
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 UpdatePrincipalTables( DbDatabaseMapping databaseMapping, EntityType toTable, bool removeFks, AssociationType associationType, EntityType et) { AssociationEndMember principalEnd, dependentEnd; var endsToCheck = new List <AssociationEndMember>(); if (associationType.TryGuessPrincipalAndDependentEnds(out principalEnd, out dependentEnd)) { endsToCheck.Add(principalEnd); } else if (associationType.SourceEnd.RelationshipMultiplicity == RelationshipMultiplicity.Many && associationType.TargetEnd.RelationshipMultiplicity == RelationshipMultiplicity.Many) { // many to many consider both ends endsToCheck.Add(associationType.SourceEnd); endsToCheck.Add(associationType.TargetEnd); } else { // 1:1 and 0..1:0..1 endsToCheck.Add(associationType.SourceEnd); } foreach (var end in endsToCheck) { if (end.GetEntityType() == et) { IEnumerable <KeyValuePair <EntityType, IEnumerable <EdmProperty> > > dependentTableInfos; if (associationType.Constraint != null) { var originalDependentType = associationType.GetOtherEnd(end).GetEntityType(); var allDependentTypes = databaseMapping.Model.GetSelfAndAllDerivedTypes(originalDependentType); dependentTableInfos = allDependentTypes.Select(t => databaseMapping.GetEntityTypeMapping(t)).Where( dm => dm != null) .SelectMany( dm => dm.MappingFragments .Where( tmf => associationType.Constraint.ToProperties .All( p => tmf.ColumnMappings.Any( pm => pm.PropertyPath.First() == p)))) .Distinct((f1, f2) => f1.Table == f2.Table) .Select( df => new KeyValuePair <EntityType, IEnumerable <EdmProperty> >( df.Table, df.ColumnMappings.Where( pm => associationType.Constraint.ToProperties.Contains( pm.PropertyPath.First())).Select( pm => pm.ColumnProperty))); } else { // IA var associationSetMapping = databaseMapping.EntityContainerMappings .Single().AssociationSetMappings .Single(asm => asm.AssociationSet.ElementType == associationType); var dependentTable = associationSetMapping.Table; var propertyMappings = associationSetMapping.SourceEndMapping.EndMember == end ? associationSetMapping.SourceEndMapping.PropertyMappings : associationSetMapping.TargetEndMapping.PropertyMappings; var dependentColumns = propertyMappings.Select(pm => pm.ColumnProperty); dependentTableInfos = new[] { new KeyValuePair <EntityType, IEnumerable <EdmProperty> >( dependentTable, dependentColumns) }; } foreach (var tableInfo in dependentTableInfos) { foreach ( var fk in tableInfo.Key.ForeignKeyBuilders.Where( fk => fk.DependentColumns.SequenceEqual(tableInfo.Value)).ToArray( )) { if (removeFks) { tableInfo.Key.RemoveForeignKey(fk); } else { fk.PrincipalTable = toTable; } } } } } }
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; }
internal static string GetFkNameM2M(AssociationType association, AssociationEndMember endWithNavProp, string keyPropertyName) { var principalEnd = association.GetOtherEnd(endWithNavProp); return(String.Format(CultureInfo.CurrentCulture, "{0}_{1}", principalEnd.GetEntityType().Name, keyPropertyName)); }