public virtual InternalRelationshipBuilder Relationship( [NotNull] InternalEntityBuilder principalEntityTypeBuilder, [NotNull] InternalEntityBuilder dependentEntityTypeBuilder, [CanBeNull] string navigationToPrincipalName, [CanBeNull] string navigationToDependentName, ConfigurationSource configurationSource, bool?oneToOne = null, bool strictPrincipal = true) { Check.NotNull(principalEntityTypeBuilder, "principalEntityTypeBuilder"); Check.NotNull(dependentEntityTypeBuilder, "dependentEntityTypeBuilder"); if (dependentEntityTypeBuilder != this) { return(dependentEntityTypeBuilder.Relationship( principalEntityTypeBuilder, dependentEntityTypeBuilder, navigationToPrincipalName, navigationToDependentName, configurationSource, oneToOne, strictPrincipal)); } if (!string.IsNullOrEmpty(navigationToPrincipalName) && !dependentEntityTypeBuilder.CanAdd(navigationToPrincipalName, isNavigation: true, configurationSource: configurationSource)) { return(null); } if (!string.IsNullOrEmpty(navigationToDependentName) && !principalEntityTypeBuilder.CanAdd(navigationToDependentName, isNavigation: true, configurationSource: configurationSource)) { return(null); } var principalEntityType = principalEntityTypeBuilder.Metadata; var dependentEntityType = dependentEntityTypeBuilder.Metadata; if (principalEntityType.TryGetPrimaryKey() == null) { if (configurationSource == ConfigurationSource.Explicit) { throw new InvalidOperationException(Strings.PrincipalEntityTypeRequiresKey(principalEntityType.Name)); } return(null); } var navigationToPrincipal = string.IsNullOrEmpty(navigationToPrincipalName) ? null : dependentEntityType.TryGetNavigation(navigationToPrincipalName); if (navigationToPrincipal != null && navigationToPrincipal.IsCompatible(principalEntityType, dependentEntityType, strictPrincipal ? (bool?)true : null, oneToOne)) { return(Relationship(navigationToPrincipal, configurationSource, navigationToDependentName)); } var navigationToDependent = string.IsNullOrEmpty(navigationToDependentName) ? null : principalEntityType.TryGetNavigation(navigationToDependentName); if (navigationToDependent != null && navigationToDependent.IsCompatible(principalEntityType, dependentEntityType, strictPrincipal? (bool?)false : null, oneToOne)) { return(Relationship(navigationToDependent, configurationSource, navigationToPrincipalName)); } if (!RemoveRelationships(configurationSource, navigationToPrincipal?.ForeignKey, navigationToDependent?.ForeignKey)) { return(null); } navigationToPrincipalName = navigationToPrincipalName == "" ? null : navigationToPrincipalName; navigationToDependentName = navigationToDependentName == "" ? null : navigationToDependentName; var foreignKey = new ForeignKeyConvention() .CreateForeignKeyByConvention( principalEntityType, dependentEntityType, navigationToPrincipalName, null, null, oneToOne); if (foreignKey == null) { return(null); } var relationshipBuilder = new InternalRelationshipBuilder(foreignKey, dependentEntityTypeBuilder.ModelBuilder, foreignKeyConfigurationSource: null); Debug.Assert(relationshipBuilder.Metadata.EntityType == Metadata); _relationshipBuilders.Value.Add(foreignKey, relationshipBuilder, configurationSource); if (navigationToPrincipalName != null) { var navigationToPrincipalSet = dependentEntityTypeBuilder .Navigation(navigationToPrincipalName, foreignKey, pointsToPrincipal: true, configurationSource: configurationSource); Debug.Assert(navigationToPrincipalSet); } if (navigationToDependentName != null) { var navigationToDependentSet = principalEntityTypeBuilder .Navigation(navigationToDependentName, foreignKey, pointsToPrincipal: false, configurationSource: configurationSource); Debug.Assert(navigationToDependentSet); } return(relationshipBuilder); }
public static RelationalForeignKeyBuilderAnnotations SqlServer( [NotNull] this InternalRelationshipBuilder builder, ConfigurationSource configurationSource) => new RelationalForeignKeyBuilderAnnotations(builder, configurationSource, SqlServerAnnotationNames.Prefix);
public virtual InternalRelationshipBuilder ReplaceForeignKey( [NotNull] InternalRelationshipBuilder relationshipBuilder, [NotNull] IReadOnlyList <Property> dependentProperties, [NotNull] IReadOnlyList <Property> principalProperties, ConfigurationSource configurationSource) { if (!_relationshipBuilders.Value.Remove(relationshipBuilder.Metadata, configurationSource)) { return(null); } // TODO: avoid removing and readding the navigation property if (relationshipBuilder.NavigationToPrincipal != null) { relationshipBuilder.DependentType.RemoveNavigation(relationshipBuilder.NavigationToPrincipal); } if (relationshipBuilder.NavigationToDependent != null) { relationshipBuilder.PrincipalType.RemoveNavigation(relationshipBuilder.NavigationToDependent); } var entityType = relationshipBuilder.Metadata.EntityType; // TODO: Remove FK only if it was added by convention // Issue #213 entityType.RemoveForeignKey(relationshipBuilder.Metadata); var newForeignKey = new ForeignKeyConvention().FindOrCreateForeignKey( relationshipBuilder.PrincipalType, relationshipBuilder.DependentType, relationshipBuilder.NavigationToPrincipal != null ? relationshipBuilder.NavigationToPrincipal.Name : null, relationshipBuilder.NavigationToDependent != null ? relationshipBuilder.NavigationToDependent.Name : null, dependentProperties, principalProperties, ((IForeignKey)relationshipBuilder.Metadata).IsUnique); // TODO: Remove principal key only if it was added by convention // Issue #213 var currentPrincipalKey = relationshipBuilder.Metadata.ReferencedKey; if (currentPrincipalKey != newForeignKey.ReferencedKey && currentPrincipalKey != currentPrincipalKey.EntityType.TryGetPrimaryKey() && currentPrincipalKey.Properties.All(p => p.IsShadowProperty)) { currentPrincipalKey.EntityType.RemoveKey(currentPrincipalKey); } var propertiesInUse = entityType.Keys.SelectMany(k => k.Properties) .Concat(entityType.ForeignKeys.SelectMany(k => k.Properties)) .Concat(relationshipBuilder.Metadata.ReferencedEntityType.Keys.SelectMany(k => k.Properties)) .Concat(relationshipBuilder.Metadata.ReferencedEntityType.ForeignKeys.SelectMany(k => k.Properties)) .Concat(dependentProperties) .Concat(principalProperties) .Where(p => p.IsShadowProperty) .Distinct(); var propertiesToRemove = Metadata.Properties .Concat(relationshipBuilder.Metadata.ReferencedKey.Properties) .Where(p => p.IsShadowProperty) .Distinct() .Except(propertiesInUse) .ToList(); // TODO: Remove property only if it was added by convention // Issue #213 foreach (var property in propertiesToRemove) { property.EntityType.RemoveProperty(property); } var navigationToPrincipal = relationshipBuilder.NavigationToPrincipal; if (navigationToPrincipal != null) { navigationToPrincipal = relationshipBuilder.DependentType.AddNavigation( navigationToPrincipal.Name, newForeignKey, navigationToPrincipal.PointsToPrincipal); } var navigationToDependent = relationshipBuilder.NavigationToDependent; if (navigationToDependent != null) { navigationToDependent = relationshipBuilder.PrincipalType.AddNavigation( navigationToDependent.Name, newForeignKey, navigationToDependent.PointsToPrincipal); } var owner = this; if (Metadata != newForeignKey.EntityType) { owner = ModelBuilder.Entity(newForeignKey.EntityType.Name, configurationSource); } var builder = owner._relationshipBuilders.Value.TryGetValue(newForeignKey, configurationSource); if (builder != null) { if (builder.PrincipalType == relationshipBuilder.PrincipalType && builder.DependentType == relationshipBuilder.DependentType && builder.NavigationToPrincipal == navigationToPrincipal && builder.NavigationToDependent == navigationToDependent) { return(builder); } if (!owner._relationshipBuilders.Value.Remove(newForeignKey, configurationSource)) { return(null); } } builder = new InternalRelationshipBuilder( relationshipBuilder, newForeignKey, navigationToPrincipal, navigationToDependent); owner._relationshipBuilders.Value.Add(newForeignKey, builder, configurationSource); return(builder); }
public static RelationalForeignKeyBuilderAnnotations Relational( [NotNull] this InternalRelationshipBuilder builder, ConfigurationSource configurationSource) => new RelationalForeignKeyBuilderAnnotations(builder, configurationSource, null);