public virtual void Apply(InternalEntityTypeBuilder entityTypeBuilder, ForeignKey foreignKey) { Check.NotNull(entityTypeBuilder, nameof(entityTypeBuilder)); Check.NotNull(foreignKey, nameof(foreignKey)); ConfigureKeyProperties(entityTypeBuilder, foreignKey.Properties); }
public virtual void Apply(InternalEntityTypeBuilder entityTypeBuilder, ForeignKey foreignKey) { Check.NotNull(entityTypeBuilder, nameof(entityTypeBuilder)); Check.NotNull(foreignKey, nameof(foreignKey)); SetValueGeneration(entityTypeBuilder, foreignKey.Properties); SetIdentity(entityTypeBuilder, foreignKey.Properties); }
public virtual void Apply(InternalEntityTypeBuilder entityTypeBuilder, ForeignKey foreignKey) { var properties = foreignKey.Properties; SetValueGeneration(entityTypeBuilder, properties); var valueGeneratedOnAddProperty = FindValueGeneratedOnAddProperty(properties); if (valueGeneratedOnAddProperty != null && entityTypeBuilder.Metadata.FindPrimaryKey(properties) != null) { SetIdentity(entityTypeBuilder, valueGeneratedOnAddProperty); } }
private bool ShouldFlip( ForeignKey foreignKey, IReadOnlyList<Property> currentDependentCandidateProperties, IReadOnlyList<Property> currentPrincipalCandidateProperties) { if (currentDependentCandidateProperties != null && currentPrincipalCandidateProperties == null) { return false; } if (currentDependentCandidateProperties == null && currentPrincipalCandidateProperties != null) { return true; } var navigationToPrincipal = foreignKey.DependentToPrincipal; var navigationToDependent = foreignKey.PrincipalToDependent; if (navigationToPrincipal == null && navigationToDependent != null) { return false; } if (navigationToPrincipal != null && navigationToDependent == null) { return true; } var model = foreignKey.DeclaringEntityType.Model; var principalPk = foreignKey.PrincipalEntityType.FindPrimaryKey(); var principalPkReferenceThreshold = foreignKey.PrincipalKey == principalPk ? 1 : 0; var isPrincipalKeyReferenced = principalPk != null && model.FindReferencingForeignKeys(principalPk).Count() > principalPkReferenceThreshold; var dependentPk = foreignKey.DeclaringEntityType.FindPrimaryKey(); var isDependentPrimaryKeyReferenced = dependentPk != null && model.FindReferencingForeignKeys(dependentPk).Any(); if (isPrincipalKeyReferenced && !isDependentPrimaryKeyReferenced) { return false; } if (!isPrincipalKeyReferenced && isDependentPrimaryKeyReferenced) { return true; } return StringComparer.Ordinal.Compare(foreignKey.PrincipalEntityType.Name, foreignKey.DeclaringEntityType.Name) > 0; }
public void Can_create_foreign_key() { var entityType = new Model().AddEntityType("E"); var dependentProp = entityType.AddProperty("P", typeof(int)); var principalProp = entityType.AddProperty("Id", typeof(int)); entityType.GetOrSetPrimaryKey(principalProp); var foreignKey = new ForeignKey(new[] { dependentProp }, entityType.FindPrimaryKey(), entityType, entityType) { IsUnique = true }; Assert.Same(entityType, foreignKey.PrincipalEntityType); Assert.Same(principalProp, foreignKey.PrincipalKey.Properties.Single()); Assert.Same(dependentProp, foreignKey.Properties.Single()); Assert.True(foreignKey.IsUnique.Value); Assert.Same(entityType.FindPrimaryKey(), foreignKey.PrincipalKey); }
private bool RemoveForeignKey(ForeignKey foreignKey, ConfigurationSource configurationSource) { var entityBuilder = Entity(foreignKey.EntityType.Type, ConfigurationSource.Convention); return(entityBuilder.RemoveForeignKey(foreignKey, configurationSource)); }
private IReadOnlyList<Property> TryFindMatchingClrProperties(ForeignKey foreignKey, string baseName, bool onDependent) { var entityType = onDependent ? foreignKey.EntityType : foreignKey.PrincipalEntityType; var propertiesToReference = onDependent ? foreignKey.PrincipalKey.Properties : foreignKey.EntityType.FindPrimaryKey()?.Properties; if (propertiesToReference == null) { return null; } var foreignKeyProperties = new List<Property>(); foreach (var referencedProperty in propertiesToReference) { var property = TryGetProperty(entityType, baseName + referencedProperty.Name, referencedProperty.ClrType.UnwrapNullableType()); if (property != null) { foreignKeyProperties.Add(property); } } if (propertiesToReference.Count == 1 && foreignKeyProperties.Count == 0) { var property = TryGetProperty(entityType, baseName + "Id", propertiesToReference.Single().ClrType.UnwrapNullableType()); if (property != null) { foreignKeyProperties.Add(property); } } if (foreignKeyProperties.Count < propertiesToReference.Count) { return null; } if (foreignKey.IsRequired == false && foreignKeyProperties.All(p => !((IProperty)p).IsNullable)) { return null; } var primaryKey = entityType.FindPrimaryKey(); if (primaryKey != null) { if (foreignKeyProperties.All(property => primaryKey.Properties.Contains(property))) { return null; } } return foreignKeyProperties; }
private IReadOnlyList<Property> GetCandidateForeignKeyProperties(ForeignKey foreignKey, bool onDependent) { var baseNames = new List<string>(); var navigation = onDependent ? foreignKey.DependentToPrincipal : foreignKey.PrincipalToDependent; if (navigation != null) { baseNames.Add(navigation.Name); } var entityTypeToReference = onDependent ? foreignKey.PrincipalEntityType : foreignKey.EntityType; baseNames.Add(entityTypeToReference.DisplayName()); baseNames.Add(""); foreach (var baseName in baseNames) { var match = TryFindMatchingClrProperties(foreignKey, baseName, onDependent); if (match != null) { return match; } } return null; }
private IReadOnlyList<Property> FindMatchingNonShadowProperties( ForeignKey foreignKey, string baseName, bool onDependent) { var dependentEntityType = onDependent ? foreignKey.DeclaringEntityType : foreignKey.PrincipalEntityType; var principalEntityType = onDependent ? foreignKey.PrincipalEntityType : foreignKey.DeclaringEntityType; var propertiesToReference = onDependent ? foreignKey.PrincipalKey.Properties : foreignKey.DeclaringEntityType.FindPrimaryKey()?.Properties; if (propertiesToReference == null) { return null; } var foreignKeyProperties = new List<Property>(); foreach (IProperty referencedProperty in propertiesToReference) { var property = TryGetProperty(dependentEntityType, baseName + referencedProperty.Name, referencedProperty.ClrType.UnwrapNullableType()); if (property != null) { foreignKeyProperties.Add(property); } } if (propertiesToReference.Count == 1 && foreignKeyProperties.Count == 0) { var property = TryGetProperty(dependentEntityType, baseName + "Id", ((IProperty)propertiesToReference.Single()).ClrType.UnwrapNullableType()); if (property != null) { foreignKeyProperties.Add(property); } } if (foreignKeyProperties.Count < propertiesToReference.Count) { return null; } if (!ForeignKey.AreCompatible( propertiesToReference, foreignKeyProperties, principalEntityType, dependentEntityType, shouldThrow: false)) { return null; } var primaryKey = dependentEntityType.FindPrimaryKey(); if (primaryKey != null) { if (foreignKeyProperties.All(property => primaryKey.Properties.Contains(property))) { return null; } } return foreignKeyProperties; }
public void Can_create_foreign_key_with_non_pk_principal() { var entityType = new Model().AddEntityType("E"); var keyProp = entityType.AddProperty("Id", typeof(int)); var dependentProp = entityType.AddProperty("P", typeof(int)); var principalProp = entityType.AddProperty("U", typeof(int)); entityType.GetOrSetPrimaryKey(keyProp); var principalKey = entityType.AddKey(principalProp); var foreignKey = new ForeignKey(new[] { dependentProp }, principalKey, entityType, entityType) { IsUnique = false }; Assert.Same(entityType, foreignKey.PrincipalEntityType); Assert.Same(principalProp, foreignKey.PrincipalKey.Properties.Single()); Assert.Same(dependentProp, foreignKey.Properties.Single()); Assert.False(foreignKey.IsUnique.Value); Assert.Same(principalKey, foreignKey.PrincipalKey); }
public void Can_change_cascade_delete_flag() { var entityType = new Model().AddEntityType("E"); var keyProp = entityType.AddProperty("Id", typeof(int)); var dependentProp = entityType.AddProperty("P", typeof(int)); var principalProp = entityType.AddProperty("U", typeof(int)); entityType.GetOrSetPrimaryKey(keyProp); var principalKey = entityType.AddKey(principalProp); var foreignKey = new ForeignKey(new[] { dependentProp }, principalKey, entityType, entityType); Assert.Null(foreignKey.DeleteBehavior); Assert.Equal(DeleteBehavior.Restrict, ((IForeignKey)foreignKey).DeleteBehavior); foreignKey.DeleteBehavior = DeleteBehavior.Cascade; Assert.Equal(DeleteBehavior.Cascade, foreignKey.DeleteBehavior); Assert.Equal(DeleteBehavior.Cascade, ((IForeignKey)foreignKey).DeleteBehavior); foreignKey.DeleteBehavior = DeleteBehavior.Restrict; Assert.Equal(DeleteBehavior.Restrict, foreignKey.DeleteBehavior); Assert.Equal(DeleteBehavior.Restrict, ((IForeignKey)foreignKey).DeleteBehavior); foreignKey.DeleteBehavior = null; Assert.Null(foreignKey.DeleteBehavior); Assert.Equal(DeleteBehavior.Restrict, ((IForeignKey)foreignKey).DeleteBehavior); }
public void Setting_IsRequired_to_false_will_set_all_FK_properties_as_nullable() { var entityType = new Model().AddEntityType("E"); var property = entityType.AddProperty("Id1", typeof(int)); var property1 = entityType.AddProperty("Id2", typeof(string)); entityType.GetOrSetPrimaryKey(new[] { property, property1 }); var dependentProp1 = entityType.AddProperty("P1", typeof(int?)); var dependentProp2 = entityType.AddProperty("P2", typeof(string)); var foreignKey = new ForeignKey(new[] { dependentProp1, dependentProp2 }, entityType.FindPrimaryKey(), entityType, entityType) { IsRequired = false }; Assert.False(foreignKey.IsRequired.Value); Assert.True(dependentProp1.IsNullable.Value); Assert.True(dependentProp2.IsNullable.Value); }
public void IsRequired_false_when_any_part_of_composite_FK_is_nullable() { var entityType = new Model().AddEntityType("E"); var property = entityType.AddProperty("Id1", typeof(int)); var property1 = entityType.AddProperty("Id2", typeof(string)); entityType.GetOrSetPrimaryKey(new[] { property, property1 }); var dependentProp1 = entityType.AddProperty("P1", typeof(int)); var dependentProp2 = entityType.AddProperty("P2", typeof(string)); dependentProp2.IsNullable = true; var foreignKey = new ForeignKey(new[] { dependentProp1, dependentProp2 }, entityType.FindPrimaryKey(), entityType, entityType); Assert.False(foreignKey.IsRequired); Assert.False(((IForeignKey)foreignKey).IsRequired); dependentProp2.IsNullable = false; Assert.True(foreignKey.IsRequired); Assert.True(((IForeignKey)foreignKey).IsRequired); }
public void IsRequired_false_for_composite_FK_by_default() { var entityType = new Model().AddEntityType("E"); var property = entityType.AddProperty("Id1", typeof(int)); var property1 = entityType.AddProperty("Id2", typeof(string)); entityType.GetOrSetPrimaryKey(new[] { property, property1 }); var dependentProp1 = entityType.AddProperty("P1", typeof(int)); var dependentProp2 = entityType.AddProperty("P2", typeof(string)); var foreignKey = new ForeignKey(new[] { dependentProp1, dependentProp2 }, entityType.FindPrimaryKey(), entityType, entityType); Assert.Null(foreignKey.IsRequired); Assert.False(((IForeignKey)foreignKey).IsRequired); }
public void IsRequired_and_IsUnique_null_when_dependent_property_nullable_by_default() { var entityType = new Model().AddEntityType("E"); var property = entityType.AddProperty("Id", typeof(int)); entityType.GetOrSetPrimaryKey(property); var dependentProp = entityType.AddProperty("P", typeof(int?)); var foreignKey = new ForeignKey(new[] { dependentProp }, entityType.FindPrimaryKey(), entityType, entityType); Assert.Null(foreignKey.IsRequired); Assert.False(((IForeignKey)foreignKey).IsRequired); Assert.Null(foreignKey.IsUnique); Assert.False(((IForeignKey)foreignKey).IsUnique); }
public void IsRequired_true_when_dependent_property_not_nullable() { var entityType = new Model().AddEntityType("E"); var property = entityType.AddProperty("Id", typeof(int)); entityType.GetOrSetPrimaryKey(property); var dependentProp = entityType.AddProperty("P", typeof(int)); dependentProp.IsNullable = false; var foreignKey = new ForeignKey(new[] { dependentProp }, entityType.FindPrimaryKey(), entityType, entityType); Assert.True(foreignKey.IsRequired); Assert.True(((IForeignKey)foreignKey).IsRequired); }