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); }
private IReadOnlyList<RelationshipCandidate> FindRelationshipCandidates(InternalEntityTypeBuilder entityTypeBuilder) { var entityType = entityTypeBuilder.Metadata; var relationshipCandidates = new Dictionary<Type, RelationshipCandidate>(); foreach (var navigationPropertyInfo in entityType.ClrType.GetRuntimeProperties().OrderBy(p => p.Name)) { var targetClrType = FindCandidateNavigationPropertyType(navigationPropertyInfo); var navigationName = navigationPropertyInfo.Name; if (targetClrType == null || entityTypeBuilder.IsIgnored(navigationName, configurationSource: ConfigurationSource.Convention)) { continue; } var candidateTargetEntityTypeBuilder = entityTypeBuilder.ModelBuilder.Entity(targetClrType, ConfigurationSource.Convention); if (candidateTargetEntityTypeBuilder == null) { continue; } RelationshipCandidate existingCandidate; if (relationshipCandidates.TryGetValue(candidateTargetEntityTypeBuilder.Metadata.ClrType, out existingCandidate)) { if (candidateTargetEntityTypeBuilder.Metadata != entityType || !existingCandidate.InverseProperties.Contains(navigationPropertyInfo)) { existingCandidate.NavigationProperties.Add(navigationPropertyInfo); } continue; } var navigations = new HashSet<PropertyInfo> { navigationPropertyInfo }; var inverseNavigationCandidates = new HashSet<PropertyInfo>(); foreach (var inversePropertyInfo in candidateTargetEntityTypeBuilder.Metadata.ClrType.GetRuntimeProperties().OrderBy(p => p.Name)) { var inverseTargetType = FindCandidateNavigationPropertyType(inversePropertyInfo); if (inverseTargetType == null || !inverseTargetType.GetTypeInfo().IsAssignableFrom(entityType.ClrType.GetTypeInfo()) || navigationPropertyInfo == inversePropertyInfo || candidateTargetEntityTypeBuilder.IsIgnored(inversePropertyInfo.Name, ConfigurationSource.Convention)) { continue; } inverseNavigationCandidates.Add(inversePropertyInfo); } relationshipCandidates[candidateTargetEntityTypeBuilder.Metadata.ClrType] = new RelationshipCandidate(candidateTargetEntityTypeBuilder, navigations, inverseNavigationCandidates); } return relationshipCandidates.Values.ToList(); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual InternalEntityTypeBuilder Apply(InternalEntityTypeBuilder entityTypeBuilder) { var entityType = entityTypeBuilder.Metadata; var clrType = entityType.ClrType; if (clrType == null) { return entityTypeBuilder; } var baseEntityType = FindClosestBaseType(entityType); return entityTypeBuilder.HasBaseType(baseEntityType, ConfigurationSource.Convention); }
public virtual void Apply(InternalEntityTypeBuilder entityTypeBuilder, ForeignKey foreignKey) { Check.NotNull(entityTypeBuilder, nameof(entityTypeBuilder)); Check.NotNull(foreignKey, nameof(foreignKey)); var properties = foreignKey.Properties; if (properties.Any(e => e.GenerateValueOnAdd == true)) { ConfigureValueGenerationStrategy(entityTypeBuilder, properties, true); } }
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); } }
public virtual InternalEntityTypeBuilder Apply(InternalEntityTypeBuilder entityTypeBuilder) { Check.NotNull(entityTypeBuilder, nameof(entityTypeBuilder)); var entityType = entityTypeBuilder.Metadata; var keyProperties = DiscoverKeyProperties(entityType); if (keyProperties.Count != 0) { entityTypeBuilder.PrimaryKey(keyProperties.Select(p => p.Name).ToList(), ConfigurationSource.Convention); } return entityTypeBuilder; }
private void SetValueGeneration(InternalEntityTypeBuilder entityTypeBuilder, IEnumerable<Property> properties) { var propertyBuilders = InternalEntityTypeBuilder.GetPropertyBuilders( entityTypeBuilder.ModelBuilder, properties.Where(property => !entityTypeBuilder.Metadata.GetForeignKeys().SelectMany(fk => fk.Properties).Contains(property) && ((IProperty)property).ValueGenerated == ValueGenerated.OnAdd), ConfigurationSource.Convention); foreach (var propertyBuilder in propertyBuilders) { propertyBuilder?.UseValueGenerator(true, ConfigurationSource.Convention); } }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual bool Apply(InternalEntityTypeBuilder entityTypeBuilder, EntityType oldBaseType) { if (oldBaseType != null && oldBaseType.BaseType == null && !oldBaseType.GetDerivedTypes().Any()) { var oldBaseTypeBuilder = oldBaseType.Builder; oldBaseTypeBuilder?.Relational(ConfigurationSource.Convention).HasDiscriminator(propertyInfo: null); } var entityType = entityTypeBuilder.Metadata; var derivedEntityTypes = entityType.GetDerivedTypes().ToList(); DiscriminatorBuilder discriminator; if (entityType.BaseType == null) { if (!derivedEntityTypes.Any()) { entityTypeBuilder.Relational(ConfigurationSource.Convention).HasDiscriminator(propertyInfo: null); return true; } discriminator = entityTypeBuilder.Relational(ConfigurationSource.Convention) .HasDiscriminator(typeof(string)); } else { if (entityTypeBuilder.Relational(ConfigurationSource.Convention).HasDiscriminator(propertyInfo: null) == null) { // TODO: log warning that the current discriminator couldn't be removed return true; } var rootTypeBuilder = entityType.RootType().Builder; discriminator = rootTypeBuilder?.Relational(ConfigurationSource.Convention).HasDiscriminator(typeof(string)); if (entityType.BaseType.BaseType == null) { discriminator?.HasValue(entityType.BaseType.Name, entityType.BaseType.DisplayName()); } } if (discriminator != null) { discriminator.HasValue(entityTypeBuilder.Metadata.Name, entityTypeBuilder.Metadata.DisplayName()); SetDefaultDiscriminatorValues(derivedEntityTypes, discriminator); } return true; }
public virtual InternalEntityTypeBuilder Apply(InternalEntityTypeBuilder entityTypeBuilder) { Check.NotNull(entityTypeBuilder, nameof(entityTypeBuilder)); if (!entityTypeBuilder.Metadata.HasClrType()) { return entityTypeBuilder; } var relationshipCandidates = FindRelationshipCandidates(entityTypeBuilder); relationshipCandidates = RemoveIncompatibleWithExistingRelationships(relationshipCandidates, entityTypeBuilder); relationshipCandidates = RemoveInheritedInverseNavigations(relationshipCandidates); CreateRelationships(relationshipCandidates, entityTypeBuilder); return entityTypeBuilder; }
public virtual InternalEntityTypeBuilder Apply(InternalEntityTypeBuilder entityTypeBuilder) { Check.NotNull(entityTypeBuilder, nameof(entityTypeBuilder)); var entityType = entityTypeBuilder.Metadata; if (entityType.HasClrType) { var primitiveProperties = entityType.ClrType.GetRuntimeProperties().Where(IsCandidatePrimitiveProperty); foreach (var propertyInfo in primitiveProperties) { entityTypeBuilder.Property(propertyInfo, ConfigurationSource.Convention); } } return entityTypeBuilder; }
public virtual InternalEntityTypeBuilder Apply(InternalEntityTypeBuilder entityTypeBuilder) { Check.NotNull(entityTypeBuilder, nameof(entityTypeBuilder)); var entityType = entityTypeBuilder.Metadata; if (entityType.BaseType == null) { var candidateProperties = entityType.GetProperties().Where(p => !((IProperty)p).IsShadowProperty || !entityTypeBuilder.CanRemoveProperty(p, ConfigurationSource.Convention)).ToList(); var keyProperties = DiscoverKeyProperties(entityType, candidateProperties); if (keyProperties.Count != 0) { entityTypeBuilder.PrimaryKey(keyProperties.Select(p => p.Name).ToList(), ConfigurationSource.Convention); } } return entityTypeBuilder; }
public void OnEntityTypeAdded_calls_apply_on_conventions_in_order(bool useBuilder) { var conventions = new ConventionSet(); InternalEntityTypeBuilder entityTypeBuilder = null; var convention = new Mock<IEntityTypeConvention>(); convention.Setup(c => c.Apply(It.IsAny<InternalEntityTypeBuilder>())).Returns<InternalEntityTypeBuilder>(b => { Assert.NotNull(b); entityTypeBuilder = new InternalEntityTypeBuilder(b.Metadata, b.ModelBuilder); return entityTypeBuilder; }); conventions.EntityTypeAddedConventions.Add(convention.Object); var nullConvention = new Mock<IEntityTypeConvention>(); nullConvention.Setup(c => c.Apply(It.IsAny<InternalEntityTypeBuilder>())).Returns<InternalEntityTypeBuilder>(b => { Assert.Same(entityTypeBuilder, b); return null; }); conventions.EntityTypeAddedConventions.Add(nullConvention.Object); var extraConvention = new Mock<IEntityTypeConvention>(); extraConvention.Setup(c => c.Apply(It.IsAny<InternalEntityTypeBuilder>())).Returns<InternalEntityTypeBuilder>(b => { Assert.False(true); return null; }); conventions.EntityTypeAddedConventions.Add(extraConvention.Object); var builder = new InternalModelBuilder(new Model(conventions)); if (useBuilder) { Assert.Null(builder.Entity(typeof(Order), ConfigurationSource.Convention)); } else { Assert.Null(builder.Metadata.AddEntityType(typeof(Order), ConfigurationSource.Convention)); } Assert.NotNull(entityTypeBuilder); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual bool Apply(InternalEntityTypeBuilder entityTypeBuilder, EntityType oldBaseType) { if (_sets != null) { var entityType = entityTypeBuilder.Metadata; if (oldBaseType == null && entityType.BaseType != null) { entityTypeBuilder.Relational(ConfigurationSource.Convention).ToTable(null); } else if (oldBaseType != null && entityType.BaseType == null && _sets.ContainsKey(entityType.ClrType)) { entityTypeBuilder.Relational(ConfigurationSource.Convention).ToTable(_sets[entityType.ClrType].Name); } } return true; }
public virtual InternalEntityTypeBuilder Apply(InternalEntityTypeBuilder entityTypeBuilder) { Check.NotNull(entityTypeBuilder, nameof(entityTypeBuilder)); var properties = entityTypeBuilder.Metadata.ClrType?.GetRuntimeProperties(); if (properties == null) { return entityTypeBuilder; } foreach (var property in properties) { var attributes = property.GetCustomAttributes<NotMappedAttribute>(inherit: true); if (attributes.Any()) { entityTypeBuilder.Ignore(property.Name, ConfigurationSource.DataAnnotation); } } return entityTypeBuilder; }
public virtual InternalEntityTypeBuilder Apply(InternalEntityTypeBuilder entityTypeBuilder) { var entityType = entityTypeBuilder.Metadata; var clrType = entityType.ClrType; if (clrType == null) { return entityTypeBuilder; } var directlyDerivedTypes = entityType.Model.GetEntityTypes().Where(t => (t.BaseType == entityType.BaseType) && t.HasClrType() && (FindClosestBaseType(t) == entityType)) .ToList(); foreach (var directlyDerivedType in directlyDerivedTypes) { entityTypeBuilder.ModelBuilder.Entity(directlyDerivedType.ClrType, ConfigurationSource.Convention) .HasBaseType(entityType, ConfigurationSource.Convention); } return entityTypeBuilder; }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual bool ApplyIgnored( [NotNull] InternalEntityTypeBuilder entityTypeBuilder, [NotNull] PropertyInfo navigationPropertyInfo, [NotNull] Type targetClrType, [NotNull] TAttribute attribute) => throw new NotImplementedException();
private static void SetNavigationCandidates( InternalEntityTypeBuilder entityTypeBuilder, ImmutableSortedDictionary <PropertyInfo, Type> navigationCandidates) => entityTypeBuilder.HasAnnotation(NavigationCandidatesAnnotationName, navigationCandidates, ConfigurationSource.Convention);
private static void SetAmbigousNavigations( InternalEntityTypeBuilder entityTypeBuilder, ImmutableSortedDictionary <MemberInfo, Type> ambiguousNavigations) => entityTypeBuilder.HasAnnotation(AmbiguousNavigationsAnnotationName, ambiguousNavigations, ConfigurationSource.Convention);
public RelationshipCandidate( InternalEntityTypeBuilder targetTypeBuilder, HashSet<PropertyInfo> navigations, HashSet<PropertyInfo> inverseNavigations) { TargetTypeBuilder = targetTypeBuilder; NavigationProperties = navigations; InverseProperties = inverseNavigations; }
public InternalEntityTypeBuilder Apply(InternalEntityTypeBuilder entityTypeBuilder) { Applied = true; return(entityTypeBuilder); }
public virtual InternalEntityTypeBuilder Apply(InternalEntityTypeBuilder entityTypeBuilder) { Check.NotNull(entityTypeBuilder, nameof(entityTypeBuilder)); var entityType = entityTypeBuilder.Metadata; var navigationPairCandidates = new Dictionary<Type, Tuple<List<PropertyInfo>, List<PropertyInfo>>>(); if (entityType.HasClrType) { foreach (var navigationPropertyInfo in entityType.ClrType.GetRuntimeProperties().OrderBy(p => p.Name)) { var entityClrType = navigationPropertyInfo.FindCandidateNavigationPropertyType(); if (entityClrType == null || !entityTypeBuilder.CanAddNavigation(navigationPropertyInfo.Name, ConfigurationSource.Convention)) { continue; } var targetEntityTypeBuilder = entityTypeBuilder.ModelBuilder.Entity(entityClrType, ConfigurationSource.Convention); if (targetEntityTypeBuilder == null) { continue; } // The navigation could have been added when the target entity type was added if (!entityTypeBuilder.CanAddNavigation(navigationPropertyInfo.Name, ConfigurationSource.Convention)) { continue; } if (navigationPairCandidates.ContainsKey(targetEntityTypeBuilder.Metadata.ClrType)) { if (entityType != targetEntityTypeBuilder.Metadata || !navigationPairCandidates[targetEntityTypeBuilder.Metadata.ClrType].Item2.Contains(navigationPropertyInfo)) { navigationPairCandidates[targetEntityTypeBuilder.Metadata.ClrType].Item1.Add(navigationPropertyInfo); } continue; } var navigations = new List<PropertyInfo> { navigationPropertyInfo }; var reverseNavigations = new List<PropertyInfo>(); navigationPairCandidates[targetEntityTypeBuilder.Metadata.ClrType] = new Tuple<List<PropertyInfo>, List<PropertyInfo>>(navigations, reverseNavigations); foreach (var reversePropertyInfo in targetEntityTypeBuilder.Metadata.ClrType.GetRuntimeProperties().OrderBy(p => p.Name)) { var reverseEntityClrType = reversePropertyInfo.FindCandidateNavigationPropertyType(); if (reverseEntityClrType == null || !targetEntityTypeBuilder.CanAddNavigation(reversePropertyInfo.Name, ConfigurationSource.Convention) || entityType.ClrType != reverseEntityClrType || navigationPropertyInfo == reversePropertyInfo) { continue; } reverseNavigations.Add(reversePropertyInfo); } } foreach (var navigationPairCandidate in navigationPairCandidates) { var navigationCandidates = navigationPairCandidate.Value.Item1; var reverseNavigationCandidates = navigationPairCandidate.Value.Item2; if (navigationCandidates.Count > 1 && reverseNavigationCandidates.Count > 0) { // Ambiguous navigations return entityTypeBuilder; } if (reverseNavigationCandidates.Count > 1) { // Ambiguous navigations return entityTypeBuilder; } foreach (var navigationCandidate in navigationCandidates) { var targetEntityTypeBuilder = entityTypeBuilder.ModelBuilder.Entity(navigationCandidate.FindCandidateNavigationPropertyType(), ConfigurationSource.Convention); targetEntityTypeBuilder.Relationship(entityTypeBuilder, navigationCandidate, reverseNavigationCandidates.SingleOrDefault(), ConfigurationSource.Convention); } } } // While running conventions on entityType, its source will be DataAnnotation or higher // Which means that entity won't be removed while being configured even if it is unreachable // This takes care of removing such unreachable entities (being run after we are done building relationships using this entity) entityTypeBuilder.ModelBuilder.RemoveEntityTypesUnreachableByNavigations(ConfigurationSource.DataAnnotation); return entityTypeBuilder; }
private static void SetDuplicateServiceProperties( InternalEntityTypeBuilder entityTypeBuilder, Dictionary <Type, HashSet <MemberInfo> > duplicateServiceProperties) => entityTypeBuilder.HasAnnotation(DuplicateServicePropertiesAnnotationName, duplicateServiceProperties, ConfigurationSource.Convention);
private InternalRelationshipBuilder ConfigureInverseNavigation( InternalEntityTypeBuilder entityTypeBuilder, MemberInfo navigationMemberInfo, InternalEntityTypeBuilder targetEntityTypeBuilder, InversePropertyAttribute attribute) { var entityType = entityTypeBuilder.Metadata; var targetClrType = targetEntityTypeBuilder.Metadata.ClrType; var inverseNavigationPropertyInfo = targetEntityTypeBuilder.Metadata.GetRuntimeProperties().Values .FirstOrDefault(p => string.Equals(p.Name, attribute.Property, StringComparison.OrdinalIgnoreCase)); if (inverseNavigationPropertyInfo == null || !FindCandidateNavigationPropertyType(inverseNavigationPropertyInfo).GetTypeInfo() .IsAssignableFrom(entityType.ClrType.GetTypeInfo())) { throw new InvalidOperationException( CoreStrings.InvalidNavigationWithInverseProperty( navigationMemberInfo.Name, entityType.DisplayName(), attribute.Property, targetClrType.ShortDisplayName())); } if (Equals(inverseNavigationPropertyInfo, navigationMemberInfo)) { throw new InvalidOperationException( CoreStrings.SelfReferencingNavigationWithInverseProperty( navigationMemberInfo.Name, entityType.DisplayName(), navigationMemberInfo.Name, entityType.DisplayName())); } // Check for InversePropertyAttribute on the inverseNavigation to verify that it matches. if (Attribute.IsDefined(inverseNavigationPropertyInfo, typeof(InversePropertyAttribute))) { var inverseAttribute = inverseNavigationPropertyInfo.GetCustomAttribute <InversePropertyAttribute>(true); if (inverseAttribute.Property != navigationMemberInfo.Name) { throw new InvalidOperationException( CoreStrings.InversePropertyMismatch( navigationMemberInfo.Name, entityType.DisplayName(), inverseNavigationPropertyInfo.Name, targetEntityTypeBuilder.Metadata.DisplayName())); } } var referencingNavigationsWithAttribute = AddInverseNavigation(entityType, navigationMemberInfo, targetEntityTypeBuilder.Metadata, inverseNavigationPropertyInfo); var ambiguousInverse = FindAmbiguousInverse( navigationMemberInfo, entityType, entityType.Model, referencingNavigationsWithAttribute); if (ambiguousInverse != null) { var existingInverse = targetEntityTypeBuilder.Metadata.FindNavigation(inverseNavigationPropertyInfo)?.FindInverse(); var existingInverseType = existingInverse?.DeclaringEntityType; if (existingInverse != null && IsAmbiguousInverse( existingInverse.GetIdentifyingMemberInfo(), existingInverseType, entityType.Model, referencingNavigationsWithAttribute)) { var fk = existingInverse.ForeignKey; if (fk.IsOwnership || fk.DeclaringEntityType.Builder.RemoveForeignKey(fk, ConfigurationSource.DataAnnotation) == null) { fk.Builder.Navigations( existingInverse.IsDependentToPrincipal() ? PropertyIdentity.None : (PropertyIdentity?)null, existingInverse.IsDependentToPrincipal() ? (PropertyIdentity?)null : PropertyIdentity.None, ConfigurationSource.DataAnnotation); } } var existingNavigation = entityTypeBuilder.Metadata.FindNavigation(navigationMemberInfo); if (existingNavigation != null) { var fk = existingNavigation.ForeignKey; if (fk.IsOwnership || fk.DeclaringEntityType.Builder.RemoveForeignKey(fk, ConfigurationSource.DataAnnotation) == null) { fk.Builder.Navigations( existingNavigation.IsDependentToPrincipal() ? PropertyIdentity.None : (PropertyIdentity?)null, existingNavigation.IsDependentToPrincipal() ? (PropertyIdentity?)null : PropertyIdentity.None, ConfigurationSource.DataAnnotation); } } var existingAmbiguousNavigation = entityType.Model.FindActualEntityType(ambiguousInverse.Value.Item2) .FindNavigation(ambiguousInverse.Value.Item1); if (existingAmbiguousNavigation != null) { var fk = existingAmbiguousNavigation.ForeignKey; if (fk.IsOwnership || fk.DeclaringEntityType.Builder.RemoveForeignKey(fk, ConfigurationSource.DataAnnotation) == null) { fk.Builder.Navigations( existingAmbiguousNavigation.IsDependentToPrincipal() ? PropertyIdentity.None : (PropertyIdentity?)null, existingAmbiguousNavigation.IsDependentToPrincipal() ? (PropertyIdentity?)null : PropertyIdentity.None, ConfigurationSource.DataAnnotation); } } return(entityTypeBuilder.Metadata.FindNavigation(navigationMemberInfo)?.ForeignKey.Builder); } var ownership = entityType.FindOwnership(); if (ownership != null && ownership.PrincipalEntityType == targetEntityTypeBuilder.Metadata && ownership.PrincipalToDependent?.GetIdentifyingMemberInfo() != inverseNavigationPropertyInfo) { _logger.NonOwnershipInverseNavigationWarning( entityType, navigationMemberInfo, targetEntityTypeBuilder.Metadata, inverseNavigationPropertyInfo, ownership.PrincipalToDependent.GetIdentifyingMemberInfo()); return(null); } if (entityType.DefiningEntityType != null && entityType.DefiningEntityType == targetEntityTypeBuilder.Metadata && entityType.DefiningNavigationName != inverseNavigationPropertyInfo.Name) { _logger.NonDefiningInverseNavigationWarning( entityType, navigationMemberInfo, targetEntityTypeBuilder.Metadata, inverseNavigationPropertyInfo, entityType.DefiningEntityType.GetRuntimeProperties()[entityType.DefiningNavigationName]); return(null); } return(entityType.Model.ShouldBeOwnedType(entityType.ClrType) && !entityType.IsInOwnershipPath(targetEntityTypeBuilder.Metadata) ? targetEntityTypeBuilder.Owns( entityTypeBuilder.Metadata.ClrType, inverseNavigationPropertyInfo, navigationMemberInfo, ConfigurationSource.Convention) : targetEntityTypeBuilder.Relationship( entityTypeBuilder, inverseNavigationPropertyInfo, navigationMemberInfo, ConfigurationSource.DataAnnotation)); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual bool Apply(InternalEntityTypeBuilder entityTypeBuilder, EntityType oldBaseType) => Apply(entityTypeBuilder) != null;
public bool Apply(InternalEntityTypeBuilder entityTypeBuilder, EntityType oldBaseType) { Apply(entityTypeBuilder); return(true); }
/// <inheritdoc /> public void Apply(InternalEntityTypeBuilder entityTypeBuilder, Key key) { Apply(entityTypeBuilder); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual InternalPropertyBuilder Attach([NotNull] InternalEntityTypeBuilder entityTypeBuilder) { var newProperty = entityTypeBuilder.Metadata.FindProperty(Metadata.Name); InternalPropertyBuilder newPropertyBuilder; var configurationSource = Metadata.GetConfigurationSource(); var typeConfigurationSource = Metadata.GetTypeConfigurationSource(); if (newProperty != null && (newProperty.GetConfigurationSource().Overrides(configurationSource) || newProperty.GetTypeConfigurationSource().Overrides(typeConfigurationSource) || (Metadata.ClrType == newProperty.ClrType && Metadata.GetIdentifyingMemberInfo()?.Name == newProperty.GetIdentifyingMemberInfo()?.Name))) { newPropertyBuilder = newProperty.Builder; newProperty.UpdateConfigurationSource(configurationSource); if (typeConfigurationSource.HasValue) { newProperty.UpdateTypeConfigurationSource(typeConfigurationSource.Value); } } else { newPropertyBuilder = Metadata.GetIdentifyingMemberInfo() == null ? entityTypeBuilder.Property(Metadata.Name, Metadata.ClrType, configurationSource, Metadata.GetTypeConfigurationSource()) : entityTypeBuilder.Property(Metadata.GetIdentifyingMemberInfo(), configurationSource); } if (newProperty == Metadata) { return(newPropertyBuilder); } newPropertyBuilder.MergeAnnotationsFrom(Metadata); var oldBeforeSaveBehaviorConfigurationSource = Metadata.GetBeforeSaveBehaviorConfigurationSource(); if (oldBeforeSaveBehaviorConfigurationSource.HasValue) { newPropertyBuilder.BeforeSave( Metadata.GetBeforeSaveBehavior(), oldBeforeSaveBehaviorConfigurationSource.Value); } var oldAfterSaveBehaviorConfigurationSource = Metadata.GetAfterSaveBehaviorConfigurationSource(); if (oldAfterSaveBehaviorConfigurationSource.HasValue) { newPropertyBuilder.AfterSave( Metadata.GetAfterSaveBehavior(), oldAfterSaveBehaviorConfigurationSource.Value); } var oldIsNullableConfigurationSource = Metadata.GetIsNullableConfigurationSource(); if (oldIsNullableConfigurationSource.HasValue) { newPropertyBuilder.IsRequired(!Metadata.IsNullable, oldIsNullableConfigurationSource.Value); } var oldIsConcurrencyTokenConfigurationSource = Metadata.GetIsConcurrencyTokenConfigurationSource(); if (oldIsConcurrencyTokenConfigurationSource.HasValue) { newPropertyBuilder.IsConcurrencyToken( Metadata.IsConcurrencyToken, oldIsConcurrencyTokenConfigurationSource.Value); } var oldValueGeneratedConfigurationSource = Metadata.GetValueGeneratedConfigurationSource(); if (oldValueGeneratedConfigurationSource.HasValue) { newPropertyBuilder.ValueGenerated(Metadata.ValueGenerated, oldValueGeneratedConfigurationSource.Value); } var oldFieldInfoConfigurationSource = Metadata.GetFieldInfoConfigurationSource(); if (oldFieldInfoConfigurationSource.HasValue) { newPropertyBuilder.HasFieldInfo(Metadata.FieldInfo, oldFieldInfoConfigurationSource.Value); } return(newPropertyBuilder); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual InternalEntityTypeBuilder Apply(InternalEntityTypeBuilder entityTypeBuilder) => !entityTypeBuilder.Metadata.HasClrType() ? entityTypeBuilder : DiscoverRelationships(entityTypeBuilder);
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual InternalEntityTypeBuilder Apply(InternalEntityTypeBuilder entityTypeBuilder) { Check.NotNull(entityTypeBuilder, nameof(entityTypeBuilder)); var entityType = entityTypeBuilder.Metadata; if (!entityType.HasClrType()) { return(entityTypeBuilder); } var candidates = entityType.GetRuntimeProperties().Values; foreach (var propertyInfo in candidates) { if (entityTypeBuilder.IsIgnored(propertyInfo.GetSimpleMemberName(), ConfigurationSource.Convention) || entityType.FindProperty(propertyInfo) != null || entityType.FindNavigation(propertyInfo) != null || !propertyInfo.IsCandidateProperty(publicOnly: false) || (propertyInfo.IsCandidateProperty() && _typeMappingSource.FindMapping(propertyInfo) != null)) { continue; } var factory = _parameterBindingFactories.FindFactory(propertyInfo.PropertyType, propertyInfo.GetSimpleMemberName()); if (factory == null) { continue; } var duplicateMap = GetDuplicateServiceProperties(entityType); if (duplicateMap != null && duplicateMap.TryGetValue(propertyInfo.PropertyType, out var duplicateServiceProperties)) { duplicateServiceProperties.Add(propertyInfo); return(entityTypeBuilder); } var otherServicePropertySameType = entityType.GetServiceProperties() .FirstOrDefault(p => p.ClrType == propertyInfo.PropertyType); if (otherServicePropertySameType != null) { if (ConfigurationSource.Convention.Overrides(otherServicePropertySameType.GetConfigurationSource())) { otherServicePropertySameType.DeclaringEntityType.RemoveServiceProperty(otherServicePropertySameType.Name); } AddDuplicateServiceProperty(entityTypeBuilder, propertyInfo); AddDuplicateServiceProperty(entityTypeBuilder, otherServicePropertySameType.GetIdentifyingMemberInfo()); return(entityTypeBuilder); } entityTypeBuilder.ServiceProperty(propertyInfo, ConfigurationSource.Convention)?.SetParameterBinding( (ServiceParameterBinding)factory.Bind(entityType, propertyInfo.PropertyType, propertyInfo.GetSimpleMemberName()), ConfigurationSource.Convention); } return(entityTypeBuilder); }
private void CreateRelationships( IEnumerable <RelationshipCandidate> relationshipCandidates, InternalEntityTypeBuilder entityTypeBuilder) { var unusedEntityTypes = new List <EntityType>(); foreach (var relationshipCandidate in relationshipCandidates) { var entityType = entityTypeBuilder.Metadata; var targetEntityType = relationshipCandidate.TargetTypeBuilder.Metadata; var isAmbiguousOnBase = entityType.BaseType != null && HasAmbiguousNavigationsTo( entityType.BaseType, targetEntityType.ClrType) || targetEntityType.BaseType != null && HasAmbiguousNavigationsTo( targetEntityType.BaseType, entityType.ClrType); if ((relationshipCandidate.NavigationProperties.Count > 1 && relationshipCandidate.InverseProperties.Count > 0 && (!targetEntityType.Model.ShouldBeOwnedType(targetEntityType.ClrType) || entityType.IsInOwnershipPath(targetEntityType))) || relationshipCandidate.InverseProperties.Count > 1 || isAmbiguousOnBase || HasDeclaredAmbiguousNavigationsTo(entityType, targetEntityType.ClrType) || HasDeclaredAmbiguousNavigationsTo(targetEntityType, entityType.ClrType)) { if (!isAmbiguousOnBase) { AddAmbiguous(entityTypeBuilder, relationshipCandidate.NavigationProperties, targetEntityType.ClrType); AddAmbiguous(targetEntityType.Builder, relationshipCandidate.InverseProperties, entityType.ClrType); _logger.MultipleNavigationProperties( relationshipCandidate.NavigationProperties.Count == 0 ? new[] { new Tuple <MemberInfo, Type>(null, targetEntityType.ClrType) } : relationshipCandidate.NavigationProperties.Select(n => new Tuple <MemberInfo, Type>(n, entityType.ClrType)), relationshipCandidate.InverseProperties.Count == 0 ? new[] { new Tuple <MemberInfo, Type>(null, targetEntityType.ClrType) } : relationshipCandidate.InverseProperties.Select(n => new Tuple <MemberInfo, Type>(n, targetEntityType.ClrType))); } foreach (var navigationProperty in relationshipCandidate.NavigationProperties) { var existingForeignKey = entityType.FindDeclaredNavigation(navigationProperty.Name)?.ForeignKey; existingForeignKey?.DeclaringEntityType.Builder .RemoveForeignKey(existingForeignKey, ConfigurationSource.Convention); } foreach (var inverseProperty in relationshipCandidate.InverseProperties) { var existingForeignKey = targetEntityType.FindDeclaredNavigation(inverseProperty.Name)?.ForeignKey; existingForeignKey?.DeclaringEntityType.Builder .RemoveForeignKey(existingForeignKey, ConfigurationSource.Convention); } unusedEntityTypes.Add(targetEntityType); continue; } foreach (var navigation in relationshipCandidate.NavigationProperties) { if (targetEntityType.Builder == null && !targetEntityType.Model.ShouldBeOwnedType(targetEntityType.ClrType)) { continue; } if (InversePropertyAttributeConvention.IsAmbiguous(entityType, navigation, targetEntityType)) { unusedEntityTypes.Add(targetEntityType); continue; } var inverse = relationshipCandidate.InverseProperties.SingleOrDefault(); if (inverse == null) { if (targetEntityType.Model.ShouldBeOwnedType(targetEntityType.ClrType) && !entityType.IsInOwnershipPath(targetEntityType)) { entityTypeBuilder.Owns( targetEntityType.ClrType, navigation, ConfigurationSource.Convention); } else { entityTypeBuilder.Navigation( targetEntityType.Builder, navigation, ConfigurationSource.Convention); } } else { if (InversePropertyAttributeConvention.IsAmbiguous(targetEntityType, inverse, entityType)) { unusedEntityTypes.Add(targetEntityType); continue; } if (targetEntityType.Model.ShouldBeOwnedType(targetEntityType.ClrType) && !entityType.IsInOwnershipPath(targetEntityType)) { entityTypeBuilder.Owns( targetEntityType.ClrType, navigation, inverse, ConfigurationSource.Convention); } else { entityTypeBuilder.Relationship( targetEntityType.Builder, navigation, inverse, ConfigurationSource.Convention); } } } if (relationshipCandidate.NavigationProperties.Count == 0) { foreach (var inverse in relationshipCandidate.InverseProperties) { if (targetEntityType.Builder == null) { continue; } if (InversePropertyAttributeConvention.IsAmbiguous(targetEntityType, inverse, entityType)) { unusedEntityTypes.Add(targetEntityType); continue; } targetEntityType.Builder.Navigation( entityTypeBuilder, inverse, ConfigurationSource.Convention); } } } foreach (var unusedEntityType in unusedEntityTypes) { if (unusedEntityType.HasDefiningNavigation() && unusedEntityType.DefiningEntityType.FindNavigation(unusedEntityType.DefiningNavigationName) == null) { entityTypeBuilder.ModelBuilder.RemoveEntityType(unusedEntityType, ConfigurationSource.Convention); } } }
public static FbEntityTypeBuilderAnnotations Firebird(this InternalEntityTypeBuilder builder, ConfigurationSource configurationSource) => new FbEntityTypeBuilderAnnotations(builder, configurationSource);
private InternalRelationshipBuilder ConfigureInverseNavigation( InternalEntityTypeBuilder entityTypeBuilder, PropertyInfo navigationPropertyInfo, InternalEntityTypeBuilder targetEntityTypeBuilder, InversePropertyAttribute attribute) { var entityType = entityTypeBuilder.Metadata; var targetClrType = targetEntityTypeBuilder.Metadata.ClrType; var inverseNavigationPropertyInfo = targetClrType.GetRuntimeProperties().FirstOrDefault(p => string.Equals(p.Name, attribute.Property, StringComparison.OrdinalIgnoreCase)); if ((inverseNavigationPropertyInfo == null) || !FindCandidateNavigationPropertyType(inverseNavigationPropertyInfo).GetTypeInfo() .IsAssignableFrom(entityType.ClrType.GetTypeInfo())) { throw new InvalidOperationException( CoreStrings.InvalidNavigationWithInverseProperty( navigationPropertyInfo.Name, entityType.DisplayName(), attribute.Property, targetClrType.ShortDisplayName())); } if (Equals(inverseNavigationPropertyInfo, navigationPropertyInfo)) { throw new InvalidOperationException( CoreStrings.SelfReferencingNavigationWithInverseProperty( navigationPropertyInfo.Name, entityType.DisplayName(), navigationPropertyInfo.Name, entityType.DisplayName())); } // Check for InversePropertyAttribute on the inverseNavigation to verify that it matches. var inverseAttribute = inverseNavigationPropertyInfo.GetCustomAttribute <InversePropertyAttribute>(true); if (inverseAttribute != null && inverseAttribute.Property != navigationPropertyInfo.Name) { throw new InvalidOperationException( CoreStrings.InversePropertyMismatch( navigationPropertyInfo.Name, entityType.DisplayName(), inverseNavigationPropertyInfo.Name, targetEntityTypeBuilder.Metadata.DisplayName())); } var referencingNavigationsWithAttribute = AddInverseNavigation(entityType, navigationPropertyInfo, targetEntityTypeBuilder.Metadata, inverseNavigationPropertyInfo); if (IsAmbiguousInverse(entityType, navigationPropertyInfo, referencingNavigationsWithAttribute)) { var existingInverse = targetEntityTypeBuilder.Metadata.FindNavigation(inverseNavigationPropertyInfo)?.FindInverse(); if (existingInverse != null && IsAmbiguousInverse(existingInverse.DeclaringEntityType, existingInverse.PropertyInfo, referencingNavigationsWithAttribute)) { var fk = existingInverse.ForeignKey; if (fk.GetConfigurationSource() == ConfigurationSource.DataAnnotation) { fk.DeclaringEntityType.Builder.RemoveForeignKey(fk, ConfigurationSource.DataAnnotation); } } return(entityTypeBuilder.Metadata.FindNavigation(navigationPropertyInfo)?.ForeignKey.Builder); } return(targetEntityTypeBuilder.Relationship( entityTypeBuilder, inverseNavigationPropertyInfo, navigationPropertyInfo, ConfigurationSource.DataAnnotation)); }
private static void RunConvention(InternalEntityTypeBuilder entityBuilder) => new ValueGenerationConvention(CreateDependencies()) .ProcessEntityTypePrimaryKeyChanged( entityBuilder, entityBuilder.Metadata.FindPrimaryKey(), null, new ConventionContext <IConventionKey>(entityBuilder.Metadata.Model.ConventionDispatcher));
private void SetIdentity(InternalEntityTypeBuilder entityTypeBuilder, Property property) => entityTypeBuilder.Property( property.Name, ((IProperty)property).ClrType, ConfigurationSource.Convention) ?.ValueGenerated(ValueGenerated.OnAdd, ConfigurationSource.Convention);
private static void RunConvention(InternalEntityTypeBuilder entityBuilder, ForeignKey foreignKey) => new ValueGenerationConvention(CreateDependencies()) .ProcessForeignKeyRemoved( entityBuilder, foreignKey, new ConventionContext <IConventionForeignKey>(entityBuilder.Metadata.Model.ConventionDispatcher));
public virtual bool Apply(InternalEntityTypeBuilder entityTypeBuilder, string ignoredMemberName) => Apply(entityTypeBuilder) != null;
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public RelationalEntityTypeBuilderAnnotations( [NotNull] InternalEntityTypeBuilder internalBuilder, ConfigurationSource configurationSource) : base(new RelationalAnnotationsBuilder(internalBuilder, configurationSource)) { }
private IReadOnlyList<RelationshipCandidate> RemoveIncompatibleWithExistingRelationships( IReadOnlyList<RelationshipCandidate> relationshipCandidates, InternalEntityTypeBuilder entityTypeBuilder) { var filteredRelationshipCandidates = new List<RelationshipCandidate>(); foreach (var relationshipCandidate in relationshipCandidates) { var targetEntityTypeBuilder = relationshipCandidate.TargetTypeBuilder; var revisitNavigations = true; while (revisitNavigations) { revisitNavigations = false; foreach (var navigationProperty in relationshipCandidate.NavigationProperties) { var existingNavigation = entityTypeBuilder.Metadata.FindNavigation(navigationProperty.Name); if (existingNavigation != null && (existingNavigation.DeclaringEntityType != entityTypeBuilder.Metadata || existingNavigation.GetTargetType() != targetEntityTypeBuilder.Metadata)) { relationshipCandidate.NavigationProperties.Remove(navigationProperty); revisitNavigations = true; break; } var compatibleInverseProperties = new List<PropertyInfo>(); Navigation existingInverse = null; foreach (var inversePropertyInfo in relationshipCandidate.InverseProperties) { if ((existingNavigation != null && !CanMergeWith(existingNavigation, inversePropertyInfo.Name, targetEntityTypeBuilder))) { continue; } existingInverse = targetEntityTypeBuilder.Metadata.FindNavigation(inversePropertyInfo.Name); if (existingInverse != null) { if (existingInverse.DeclaringEntityType != targetEntityTypeBuilder.Metadata || !CanMergeWith(existingInverse, navigationProperty.Name, entityTypeBuilder)) { continue; } var otherEntityType = existingInverse.ForeignKey.ResolveOtherEntityType( existingInverse.DeclaringEntityType); if (!entityTypeBuilder.Metadata.ClrType.GetTypeInfo() .IsAssignableFrom(otherEntityType.ClrType.GetTypeInfo())) { continue; } } compatibleInverseProperties.Add(inversePropertyInfo); } if (compatibleInverseProperties.Count == 0) { relationshipCandidate.NavigationProperties.Remove(navigationProperty); revisitNavigations = true; filteredRelationshipCandidates.Add(new RelationshipCandidate( targetEntityTypeBuilder, new HashSet<PropertyInfo> { navigationProperty }, new HashSet<PropertyInfo>())); if (relationshipCandidate.TargetTypeBuilder.Metadata == entityTypeBuilder.Metadata && relationshipCandidate.InverseProperties.Count > 0) { var nextSelfRefCandidate = relationshipCandidate.InverseProperties.First(); relationshipCandidate.NavigationProperties.Add(nextSelfRefCandidate); relationshipCandidate.InverseProperties.Remove(nextSelfRefCandidate); } break; } if (compatibleInverseProperties.Count == 1 && (relationshipCandidate.NavigationProperties.Count == 1 || (existingInverse != null && !CanMergeWith(existingInverse, null, entityTypeBuilder)))) { var inverseProperty = compatibleInverseProperties[0]; relationshipCandidate.NavigationProperties.Remove(navigationProperty); relationshipCandidate.InverseProperties.Remove(inverseProperty); revisitNavigations = true; filteredRelationshipCandidates.Add(new RelationshipCandidate( targetEntityTypeBuilder, new HashSet<PropertyInfo> { navigationProperty }, new HashSet<PropertyInfo> { inverseProperty })); if (relationshipCandidate.TargetTypeBuilder.Metadata == entityTypeBuilder.Metadata && relationshipCandidate.InverseProperties.Count > 0) { var nextSelfRefCandidate = relationshipCandidate.InverseProperties.First(); relationshipCandidate.NavigationProperties.Add(nextSelfRefCandidate); relationshipCandidate.InverseProperties.Remove(nextSelfRefCandidate); } break; } } } if (relationshipCandidate.NavigationProperties.Count > 0) { filteredRelationshipCandidates.Add(relationshipCandidate); } } return filteredRelationshipCandidates; }
public virtual void Apply(InternalEntityTypeBuilder entityTypeBuilder, ForeignKey foreignKey) { var properties = foreignKey.Properties; SetValueGeneration(properties.Where(property => property.IsKey())); SetIdentity(properties, entityTypeBuilder.Metadata); }
public InternalEntityTypeBuilder Apply(InternalEntityTypeBuilder entityTypeBuilder) { Applied = true; return entityTypeBuilder; }
/// <summary> /// <para> /// Initializes a new instance of the <see cref="EntityTypeBuilder{TEntity}" /> class to configure a /// given entity type. /// </para> /// <para> /// Instances of this class are returned from methods when using the <see cref="ModelBuilder" /> API /// and it is not designed to be directly constructed in your application code. /// </para> /// </summary> /// <param name="builder"> Internal typeBuilder for the entity type being configured. </param> public EntityTypeBuilder([NotNull] InternalEntityTypeBuilder builder) : base(builder) { }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual InternalSkipNavigationBuilder Attach( [CanBeNull] InternalEntityTypeBuilder entityTypeBuilder = null, [CanBeNull] EntityType targetEntityType = null, [CanBeNull] InternalSkipNavigationBuilder inverseBuilder = null) { entityTypeBuilder ??= Metadata.DeclaringEntityType.Builder; if (entityTypeBuilder == null) { entityTypeBuilder = Metadata.DeclaringEntityType.Model.FindEntityType(Metadata.DeclaringEntityType.Name)?.Builder; if (entityTypeBuilder == null) { return(null); } } targetEntityType ??= Metadata.TargetEntityType; if (targetEntityType.Builder == null) { targetEntityType = Metadata.DeclaringEntityType.Model.FindEntityType(targetEntityType.Name); if (targetEntityType == null) { return(null); } } var newSkipNavigationBuilder = entityTypeBuilder.HasSkipNavigation( Metadata.CreateMemberIdentity(), targetEntityType, Metadata.GetConfigurationSource(), Metadata.IsCollection, Metadata.IsOnDependent); if (newSkipNavigationBuilder == null) { return(null); } newSkipNavigationBuilder.MergeAnnotationsFrom(Metadata); var foreignKeyConfigurationSource = Metadata.GetForeignKeyConfigurationSource(); if (foreignKeyConfigurationSource.HasValue) { var foreignKey = Metadata.ForeignKey; if (foreignKey.Builder == null) { foreignKey = InternalForeignKeyBuilder.FindCurrentForeignKeyBuilder( foreignKey.PrincipalEntityType, foreignKey.DeclaringEntityType, foreignKey.DependentToPrincipal?.CreateMemberIdentity(), foreignKey.PrincipalToDependent?.CreateMemberIdentity(), dependentProperties: foreignKey.Properties, principalProperties: foreignKey.PrincipalKey.Properties)?.Metadata; } if (foreignKey != null) { newSkipNavigationBuilder.HasForeignKey(foreignKey, foreignKeyConfigurationSource.Value); } } var inverseConfigurationSource = Metadata.GetInverseConfigurationSource(); if (inverseConfigurationSource.HasValue) { var inverse = Metadata.Inverse; if (inverse.Builder == null) { inverse = inverse.DeclaringEntityType.FindSkipNavigation(inverse.Name); } if (inverseBuilder != null) { inverse = inverseBuilder.Attach(targetEntityType.Builder, entityTypeBuilder.Metadata)?.Metadata ?? inverse; } if (inverse != null) { newSkipNavigationBuilder.HasInverse(inverse, inverseConfigurationSource.Value); } } var propertyAccessModeConfigurationSource = Metadata.GetPropertyAccessModeConfigurationSource(); if (propertyAccessModeConfigurationSource.HasValue) { newSkipNavigationBuilder.UsePropertyAccessMode( ((ISkipNavigation)Metadata).GetPropertyAccessMode(), propertyAccessModeConfigurationSource.Value); } var oldFieldInfoConfigurationSource = Metadata.GetFieldInfoConfigurationSource(); if (oldFieldInfoConfigurationSource.HasValue && newSkipNavigationBuilder.CanSetField(Metadata.FieldInfo, oldFieldInfoConfigurationSource)) { newSkipNavigationBuilder.HasField(Metadata.FieldInfo, oldFieldInfoConfigurationSource.Value); } return(newSkipNavigationBuilder); }
private IReadOnlyList <RelationshipCandidate> FindRelationshipCandidates(InternalEntityTypeBuilder entityTypeBuilder) { var relationshipCandidates = new Dictionary <EntityType, RelationshipCandidate>(); var ownership = entityTypeBuilder.Metadata.FindOwnership(); if (ownership == null && entityTypeBuilder.Metadata.Model.ShouldBeOwnedType(entityTypeBuilder.Metadata.ClrType)) { return(relationshipCandidates.Values.ToList()); } var navigationCandidates = GetNavigationCandidates(entityTypeBuilder.Metadata); foreach (var candidateTuple in navigationCandidates) { var navigationPropertyInfo = candidateTuple.Key; var targetClrType = candidateTuple.Value; if (!IsCandidateNavigationProperty(entityTypeBuilder, navigationPropertyInfo.Name, navigationPropertyInfo)) { continue; } InternalEntityTypeBuilder candidateTargetEntityTypeBuilder = null; if (!entityTypeBuilder.ModelBuilder.Metadata.HasEntityTypeWithDefiningNavigation(targetClrType)) { candidateTargetEntityTypeBuilder = entityTypeBuilder.ModelBuilder.Entity(targetClrType, ConfigurationSource.Convention); } else if (!targetClrType.GetTypeInfo().Equals(entityTypeBuilder.Metadata.ClrType.GetTypeInfo()) && !entityTypeBuilder.Metadata.IsInDefinitionPath(targetClrType)) { candidateTargetEntityTypeBuilder = entityTypeBuilder.Metadata.FindNavigation(navigationPropertyInfo.Name)?.GetTargetType().Builder ?? entityTypeBuilder.ModelBuilder.Metadata.FindEntityType( targetClrType, navigationPropertyInfo.Name, entityTypeBuilder.Metadata)?.Builder ?? entityTypeBuilder.ModelBuilder.Entity( targetClrType, navigationPropertyInfo.Name, entityTypeBuilder.Metadata, ConfigurationSource.Convention); } if (candidateTargetEntityTypeBuilder == null || (entityTypeBuilder.ModelBuilder.Metadata.ShouldBeOwnedType(entityTypeBuilder.Metadata.ClrType) && candidateTargetEntityTypeBuilder.Metadata == entityTypeBuilder.Metadata)) { continue; } var candidateTargetEntityType = candidateTargetEntityTypeBuilder.Metadata; if (candidateTargetEntityType.IsQueryType) { continue; } if (!entityTypeBuilder.Metadata.Model.ShouldBeOwnedType(candidateTargetEntityType.ClrType)) { var targetOwnership = candidateTargetEntityType.FindOwnership(); if (targetOwnership != null && (targetOwnership.PrincipalEntityType != entityTypeBuilder.Metadata || targetOwnership.PrincipalToDependent.Name != navigationPropertyInfo.Name)) { if (ownership == null || ownership.PrincipalEntityType != candidateTargetEntityType) { continue; } } } else if ( // #8172 //ownership != null && navigationPropertyInfo.PropertyType.TryGetSequenceType() != null) { continue; } var entityType = entityTypeBuilder.Metadata; if (relationshipCandidates.TryGetValue(candidateTargetEntityType, out var existingCandidate)) { if (candidateTargetEntityType != entityType || !existingCandidate.InverseProperties.Contains(navigationPropertyInfo)) { if (!existingCandidate.NavigationProperties.Contains(navigationPropertyInfo)) { existingCandidate.NavigationProperties.Add(navigationPropertyInfo); } } continue; } var navigations = new List <PropertyInfo> { navigationPropertyInfo }; var inverseCandidates = GetNavigationCandidates(candidateTargetEntityType); var inverseNavigationCandidates = new List <PropertyInfo>(); foreach (var inverseCandidateTuple in inverseCandidates) { var inversePropertyInfo = inverseCandidateTuple.Key; var inverseTargetType = inverseCandidateTuple.Value; if (inverseTargetType != entityType.ClrType || navigationPropertyInfo.IsSameAs(inversePropertyInfo) || entityType.IsQueryType || (ownership != null && (ownership.PrincipalEntityType != candidateTargetEntityType || ownership.PrincipalToDependent.Name != inversePropertyInfo.Name)) || (entityType.HasDefiningNavigation() && (entityType.DefiningEntityType != candidateTargetEntityType || entityType.DefiningNavigationName != inversePropertyInfo.Name)) || !IsCandidateNavigationProperty( candidateTargetEntityTypeBuilder, inversePropertyInfo.Name, inversePropertyInfo)) { continue; } if (!inverseNavigationCandidates.Contains(inversePropertyInfo)) { inverseNavigationCandidates.Add(inversePropertyInfo); } } relationshipCandidates[candidateTargetEntityType] = new RelationshipCandidate(candidateTargetEntityTypeBuilder, navigations, inverseNavigationCandidates); } return(relationshipCandidates.Values.ToList()); }
protected override EntityTypeBuilder New(InternalEntityTypeBuilder builder) => new EntityTypeBuilder <TEntity>(builder);
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual InternalEntityTypeBuilder Apply(InternalEntityTypeBuilder entityTypeBuilder) { Check.NotNull(entityTypeBuilder, nameof(entityTypeBuilder)); var entityType = entityTypeBuilder.Metadata; if (entityType.BaseType != null || entityType.IsQueryType || !ConfigurationSource.Convention.Overrides(entityType.GetPrimaryKeyConfigurationSource())) { return(entityTypeBuilder); } List <Property> keyProperties = null; var definingFk = entityType.FindDefiningNavigation()?.ForeignKey ?? entityType.FindOwnership(); if (definingFk != null && definingFk.DeclaringEntityType != entityType) { definingFk = null; } if (definingFk?.IsUnique == true) { keyProperties = definingFk.Properties.ToList(); } if (keyProperties == null) { var candidateProperties = entityType.GetProperties().Where( p => !p.IsShadowProperty || !ConfigurationSource.Convention.Overrides(p.GetConfigurationSource())).ToList(); keyProperties = (List <Property>)DiscoverKeyProperties(entityType, candidateProperties); if (keyProperties.Count > 1) { Logger?.MultiplePrimaryKeyCandidates(keyProperties[0], keyProperties[1]); return(entityTypeBuilder); } } if (definingFk?.IsUnique == false) { if (keyProperties.Count == 0 || definingFk.Properties.Contains(keyProperties.First())) { var shadowProperty = entityType.FindPrimaryKey()?.Properties.Last(); if (shadowProperty == null || entityType.FindPrimaryKey().Properties.Count == 1 || definingFk.Properties.Contains(shadowProperty)) { shadowProperty = entityTypeBuilder.CreateUniqueProperty("Id", typeof(int), isRequired: true); } keyProperties.Clear(); keyProperties.Add(shadowProperty); } var extraProperty = keyProperties[0]; keyProperties.RemoveAt(0); keyProperties.AddRange(definingFk.Properties); keyProperties.Add(extraProperty); } if (keyProperties.Count > 0) { entityTypeBuilder.PrimaryKey(keyProperties, ConfigurationSource.Convention); } return(entityTypeBuilder); }
private static void VerifyOneToManyDependent(InternalEntityTypeBuilder entityTypeBuilder, bool unidirectional, bool dependentHasPK = true) { VerifyOneToMany(entityTypeBuilder.Metadata.Model, dependentHasPK, hasNavigationToDependent: !unidirectional, hasNavigationToPrincipal: true); }
public void Can_ignore_property_that_is_part_of_lower_source_index() { var modelBuilder = CreateModelBuilder(); var entityType = modelBuilder.Metadata.AddEntityType(typeof(Order)); var entityBuilder = new InternalEntityTypeBuilder(entityType, modelBuilder); Assert.NotNull(entityBuilder.Index(new[] { Order.IdProperty, Order.CustomerIdProperty }, ConfigurationSource.DataAnnotation)); Assert.True(entityBuilder.Ignore(Order.CustomerIdProperty.Name, ConfigurationSource.Explicit)); Assert.Empty(entityBuilder.Metadata.Properties.Where(p => p.Name == Order.CustomerIdProperty.Name)); Assert.Empty(entityBuilder.Metadata.Indexes); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual bool Apply(InternalEntityTypeBuilder entityTypeBuilder, string ignoredMemberName) { Apply(entityTypeBuilder.Metadata); return(true); }
private static IReadOnlyList <RelationshipCandidate> RemoveIncompatibleWithExistingRelationships( IReadOnlyList <RelationshipCandidate> relationshipCandidates, InternalEntityTypeBuilder entityTypeBuilder) { if (relationshipCandidates.Count == 0) { return(relationshipCandidates); } var filteredRelationshipCandidates = new List <RelationshipCandidate>(); foreach (var relationshipCandidate in relationshipCandidates) { var targetEntityTypeBuilder = relationshipCandidate.TargetTypeBuilder; while (relationshipCandidate.NavigationProperties.Count > 0) { var navigationProperty = relationshipCandidate.NavigationProperties[0]; var existingNavigation = entityTypeBuilder.Metadata.FindNavigation(navigationProperty.Name); if (existingNavigation != null && (existingNavigation.DeclaringEntityType != entityTypeBuilder.Metadata || existingNavigation.GetTargetType() != targetEntityTypeBuilder.Metadata)) { relationshipCandidate.NavigationProperties.Remove(navigationProperty); continue; } if (relationshipCandidate.NavigationProperties.Count == 1 && relationshipCandidate.InverseProperties.Count == 0) { break; } PropertyInfo compatibleInverse = null; foreach (var inverseProperty in relationshipCandidate.InverseProperties) { if (IsCompatibleInverse( navigationProperty, inverseProperty, entityTypeBuilder, targetEntityTypeBuilder)) { if (compatibleInverse == null) { compatibleInverse = inverseProperty; } else { goto NextCandidate; } } } if (compatibleInverse == null) { relationshipCandidate.NavigationProperties.Remove(navigationProperty); filteredRelationshipCandidates.Add( new RelationshipCandidate( targetEntityTypeBuilder, new List <PropertyInfo> { navigationProperty }, new List <PropertyInfo>())); if (relationshipCandidate.TargetTypeBuilder.Metadata == entityTypeBuilder.Metadata && relationshipCandidate.InverseProperties.Count > 0) { var nextSelfRefCandidate = relationshipCandidate.InverseProperties.First(); if (!relationshipCandidate.NavigationProperties.Contains(nextSelfRefCandidate)) { relationshipCandidate.NavigationProperties.Add(nextSelfRefCandidate); } relationshipCandidate.InverseProperties.Remove(nextSelfRefCandidate); } continue; } var noOtherCompatibleNavigation = true; foreach (var n in relationshipCandidate.NavigationProperties) { if (n != navigationProperty && IsCompatibleInverse(n, compatibleInverse, entityTypeBuilder, targetEntityTypeBuilder)) { noOtherCompatibleNavigation = false; break; } } if (noOtherCompatibleNavigation) { relationshipCandidate.NavigationProperties.Remove(navigationProperty); relationshipCandidate.InverseProperties.Remove(compatibleInverse); filteredRelationshipCandidates.Add( new RelationshipCandidate( targetEntityTypeBuilder, new List <PropertyInfo> { navigationProperty }, new List <PropertyInfo> { compatibleInverse }) ); if (relationshipCandidate.TargetTypeBuilder.Metadata == entityTypeBuilder.Metadata && relationshipCandidate.NavigationProperties.Count == 0 && relationshipCandidate.InverseProperties.Count > 0) { var nextSelfRefCandidate = relationshipCandidate.InverseProperties.First(); if (!relationshipCandidate.NavigationProperties.Contains(nextSelfRefCandidate)) { relationshipCandidate.NavigationProperties.Add(nextSelfRefCandidate); } relationshipCandidate.InverseProperties.Remove(nextSelfRefCandidate); } continue; } NextCandidate: break; } if (relationshipCandidate.NavigationProperties.Count > 0 || relationshipCandidate.InverseProperties.Count > 0) { filteredRelationshipCandidates.Add(relationshipCandidate); } else if (relationshipCandidate.TargetTypeBuilder.Metadata.HasDefiningNavigation() && filteredRelationshipCandidates.All( c => c.TargetTypeBuilder.Metadata != relationshipCandidate.TargetTypeBuilder.Metadata)) { entityTypeBuilder.ModelBuilder .RemoveEntityType(relationshipCandidate.TargetTypeBuilder.Metadata, ConfigurationSource.Convention); } } return(filteredRelationshipCandidates); }
private void CreateRelationships( IReadOnlyList<RelationshipCandidate> relationshipCandidates, InternalEntityTypeBuilder entityTypeBuilder) { foreach (var relationshipCandidate in relationshipCandidates) { if ((relationshipCandidate.NavigationProperties.Count > 1 && relationshipCandidate.InverseProperties.Count > 0) || relationshipCandidate.InverseProperties.Count > 1) { foreach (var navigationProperty in relationshipCandidate.NavigationProperties) { var existingForeignKey = entityTypeBuilder.Metadata.FindDeclaredNavigation(navigationProperty.Name)?.ForeignKey; if (existingForeignKey != null) { entityTypeBuilder.ModelBuilder.Entity(existingForeignKey.DeclaringEntityType.Name, ConfigurationSource.Convention) .RemoveForeignKey(existingForeignKey, ConfigurationSource.Convention); } } foreach (var inverseProperty in relationshipCandidate.InverseProperties) { var existingForeignKey = relationshipCandidate.TargetTypeBuilder.Metadata.FindDeclaredNavigation(inverseProperty.Name)?.ForeignKey; if (existingForeignKey != null) { entityTypeBuilder.ModelBuilder.Entity(existingForeignKey.DeclaringEntityType.Name, ConfigurationSource.Convention) .RemoveForeignKey(existingForeignKey, ConfigurationSource.Convention); } } break; } foreach (var navigation in relationshipCandidate.NavigationProperties) { var inverse = relationshipCandidate.InverseProperties.SingleOrDefault(); entityTypeBuilder.Relationship( relationshipCandidate.TargetTypeBuilder, navigation, inverse, ConfigurationSource.Convention); } } }
private void SetIdentity(InternalEntityTypeBuilder entityTypeBuilder, Property property) { var propertyBuilder = entityTypeBuilder.Property( property.Name, ((IProperty)property).ClrType, ConfigurationSource.Convention); propertyBuilder?.ValueGenerated(ValueGenerated.OnAdd, ConfigurationSource.Convention); propertyBuilder?.UseValueGenerator(true, ConfigurationSource.Convention); }
public virtual bool Apply(InternalEntityTypeBuilder entityTypeBuilder, EntityType oldBaseType) { if (oldBaseType != null) { var oldBaseTypeBuilder = entityTypeBuilder.ModelBuilder.Entity(oldBaseType.Name, ConfigurationSource.Convention); if (oldBaseTypeBuilder != null) { ApplyOnRelatedEntityTypes(entityTypeBuilder.ModelBuilder, oldBaseTypeBuilder.Metadata); Apply(oldBaseTypeBuilder); } } ApplyOnRelatedEntityTypes(entityTypeBuilder.ModelBuilder, entityTypeBuilder.Metadata); return Apply(entityTypeBuilder) != null; }
public virtual InternalEntityTypeBuilder Apply(InternalEntityTypeBuilder entityTypeBuilder) { Check.NotNull(entityTypeBuilder, nameof(entityTypeBuilder)); var entityType = entityTypeBuilder.Metadata; var navigationPairCandidates = new Dictionary<InternalEntityTypeBuilder, Tuple<List<PropertyInfo>, List<PropertyInfo>>>(); if (entityType.HasClrType) { foreach (var navigationPropertyInfo in entityType.ClrType.GetRuntimeProperties().OrderBy(p => p.Name)) { Type entityClrType; if (!navigationPropertyInfo.IsCandidateNavigationProperty(out entityClrType) || !entityTypeBuilder.CanAddNavigation(navigationPropertyInfo.Name, ConfigurationSource.Convention)) { continue; } var targetEntityTypeBuilder = entityTypeBuilder.ModelBuilder.Entity(entityClrType, ConfigurationSource.Convention); if (targetEntityTypeBuilder == null) { continue; } // The navigation could have been added when the target entity type was added if (!entityTypeBuilder.CanAddNavigation(navigationPropertyInfo.Name, ConfigurationSource.Convention)) { continue; } if (navigationPairCandidates.ContainsKey(targetEntityTypeBuilder)) { if (entityType != targetEntityTypeBuilder.Metadata || !navigationPairCandidates[targetEntityTypeBuilder].Item2.Contains(navigationPropertyInfo)) { navigationPairCandidates[targetEntityTypeBuilder].Item1.Add(navigationPropertyInfo); } continue; } var navigations = new List<PropertyInfo> { navigationPropertyInfo }; var reverseNavigations = new List<PropertyInfo>(); navigationPairCandidates[targetEntityTypeBuilder] = new Tuple<List<PropertyInfo>, List<PropertyInfo>>(navigations, reverseNavigations); foreach (var reversePropertyInfo in targetEntityTypeBuilder.Metadata.ClrType.GetRuntimeProperties().OrderBy(p => p.Name)) { Type reverseEntityClrType; if (!reversePropertyInfo.IsCandidateNavigationProperty(out reverseEntityClrType) || !targetEntityTypeBuilder.CanAddNavigation(reversePropertyInfo.Name, ConfigurationSource.Convention) || entityType.ClrType != reverseEntityClrType || navigationPropertyInfo == reversePropertyInfo) { continue; } reverseNavigations.Add(reversePropertyInfo); } } foreach (var navigationPairCandidate in navigationPairCandidates) { var targetEntityTypeBuilder = navigationPairCandidate.Key; var navigationCandidates = navigationPairCandidate.Value.Item1; var reverseNavigationCandidates = navigationPairCandidate.Value.Item2; if (navigationCandidates.Count > 1 && reverseNavigationCandidates.Count > 0) { // Ambiguous navigations return entityTypeBuilder; } if (reverseNavigationCandidates.Count > 1) { // Ambiguous navigations return entityTypeBuilder; } foreach (var navigationCandidate in navigationCandidates) { TryBuildRelationship(entityTypeBuilder, targetEntityTypeBuilder, navigationCandidate, reverseNavigationCandidates.SingleOrDefault()); } } } return entityTypeBuilder; }
private InternalRelationshipBuilder ReuniquifyTemporaryProperties(ForeignKey foreignKey, bool force) { if (!force && (foreignKey.GetPropertiesConfigurationSource() != null || !foreignKey.DeclaringEntityType.Builder.ShouldReuniquifyTemporaryProperties( foreignKey.Properties, foreignKey.PrincipalKey.Properties, foreignKey.IsRequired && foreignKey.GetIsRequiredConfigurationSource().Overrides(ConfigurationSource.Convention), GetPropertyBaseName(foreignKey)))) { return(foreignKey.Builder); } var relationshipBuilder = foreignKey.Builder; using (var batch = foreignKey.DeclaringEntityType.Model.ConventionDispatcher.StartBatch()) { var temporaryProperties = foreignKey.Properties.Where( p => p.IsShadowProperty() && ConfigurationSource.Convention.Overrides(p.GetConfigurationSource())).ToList(); var keysToDetach = temporaryProperties.SelectMany( p => p.GetContainingKeys() .Where(k => ConfigurationSource.Convention.Overrides(k.GetConfigurationSource()))) .Distinct().ToList(); List <RelationshipSnapshot> detachedRelationships = null; foreach (var key in keysToDetach) { foreach (var referencingForeignKey in key.GetReferencingForeignKeys().ToList()) { if (detachedRelationships == null) { detachedRelationships = new List <RelationshipSnapshot>(); } detachedRelationships.Add(InternalEntityTypeBuilder.DetachRelationship(referencingForeignKey)); } } var detachedKeys = InternalEntityTypeBuilder.DetachKeys(keysToDetach); var detachedIndexes = InternalEntityTypeBuilder.DetachIndexes( temporaryProperties.SelectMany(p => p.GetContainingIndexes()).Distinct()); relationshipBuilder = relationshipBuilder.HasForeignKey((IReadOnlyList <Property>)null, ConfigurationSource.Convention); if (detachedIndexes != null) { foreach (var indexBuilderTuple in detachedIndexes) { indexBuilderTuple.Attach(indexBuilderTuple.Metadata.DeclaringEntityType.Builder); } } if (detachedKeys != null) { foreach (var detachedKeyTuple in detachedKeys) { detachedKeyTuple.Item1.Attach(foreignKey.DeclaringEntityType.RootType().Builder, detachedKeyTuple.Item2); } } if (detachedRelationships != null) { foreach (var detachedRelationship in detachedRelationships) { detachedRelationship.Attach(); } } return(batch.Run(relationshipBuilder)); } }
private void SetInverseNavigations( InternalEntityTypeBuilder entityTypeBuilder, Dictionary <PropertyInfo, List <Tuple <PropertyInfo, Type> > > inverseNavigations) => entityTypeBuilder.HasAnnotation(InverseNavigationsAnnotationName, inverseNavigations, ConfigurationSource.Convention);
public virtual bool Apply( InternalEntityTypeBuilder sourceEntityTypeBuilder, InternalEntityTypeBuilder targetEntityTypeBuilder, string navigationName) { if (sourceEntityTypeBuilder.IsIgnored(navigationName, ConfigurationSource.Convention)) { return true; } Apply(sourceEntityTypeBuilder); foreach (var derivedType in sourceEntityTypeBuilder.Metadata.GetDerivedTypes()) { Apply(sourceEntityTypeBuilder.ModelBuilder.Entity(derivedType.Name, ConfigurationSource.Convention)); } return true; }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual InternalEntityTypeBuilder OnBaseEntityTypeChanged( [NotNull] InternalEntityTypeBuilder entityTypeBuilder, [CanBeNull] EntityType previousBaseType) => _scope.OnBaseEntityTypeChanged(Check.NotNull(entityTypeBuilder, nameof(entityTypeBuilder)), previousBaseType);
private static void ConfigureKeys(InternalEntityTypeBuilder entityTypeBuilder) { entityTypeBuilder.PrimaryKey(new[] { "Id" }, ConfigurationSource.Convention); }