public virtual void Ambiguous_relationship_between_owned_types_throws() { var modelBuilder = CreateModelBuilder(); modelBuilder.Owned <Order>(); modelBuilder.Entity <SpecialCustomer>().OwnsMany(c => c.SpecialOrders); Assert.Equal(CoreStrings.AmbiguousOwnedNavigation(nameof(SpecialOrder), nameof(BackOrder)), Assert.Throws <InvalidOperationException>(() => modelBuilder.Validate()).Message); }
public virtual void Ambiguous_relationship_between_owned_types_throws() { var modelBuilder = CreateModelBuilder(); modelBuilder.Owned <Whoopper>(); modelBuilder.Owned <Moostard>(); modelBuilder.Entity <ToastedBun>(); Assert.Equal(CoreStrings.AmbiguousOwnedNavigation(nameof(Moostard), nameof(Whoopper)), Assert.Throws <InvalidOperationException>(() => modelBuilder.Validate()).Message); }
/// <summary> /// Validates property mappings. /// </summary> /// <param name="model"> The model. </param> /// <param name="logger"> The logger to use. </param> protected virtual void ValidatePropertyMapping([NotNull] IModel model, [NotNull] IDiagnosticsLogger <DbLoggerCategory.Model.Validation> logger) { Check.NotNull(model, nameof(model)); if (!(model is IConventionModel conventionModel)) { return; } foreach (var entityType in conventionModel.GetEntityTypes()) { var unmappedProperty = entityType.GetProperties().FirstOrDefault( p => (!ConfigurationSource.Convention.Overrides(p.GetConfigurationSource()) || !p.IsShadowProperty()) && !IsMappedPrimitiveProperty(p)); if (unmappedProperty != null) { throw new InvalidOperationException( CoreStrings.PropertyNotMapped( entityType.DisplayName(), unmappedProperty.Name, unmappedProperty.ClrType.ShortDisplayName())); } if (!entityType.HasClrType()) { continue; } var clrProperties = new HashSet <string>(StringComparer.Ordinal); var runtimeProperties = entityType.AsEntityType().GetRuntimeProperties(); clrProperties.UnionWith( runtimeProperties.Values .Where(pi => pi.IsCandidateProperty()) .Select(pi => pi.GetSimpleMemberName())); clrProperties.ExceptWith(entityType.GetProperties().Select(p => p.Name)); clrProperties.ExceptWith(entityType.GetNavigations().Select(p => p.Name)); clrProperties.ExceptWith(entityType.GetServiceProperties().Select(p => p.Name)); clrProperties.RemoveWhere(p => entityType.FindIgnoredConfigurationSource(p) != null); if (clrProperties.Count <= 0) { continue; } foreach (var clrProperty in clrProperties) { var actualProperty = runtimeProperties[clrProperty]; var propertyType = actualProperty.PropertyType; var targetSequenceType = propertyType.TryGetSequenceType(); if (conventionModel.FindIgnoredConfigurationSource(propertyType.DisplayName()) != null || targetSequenceType != null && conventionModel.FindIgnoredConfigurationSource(targetSequenceType.DisplayName()) != null) { continue; } var targetType = FindCandidateNavigationPropertyType(actualProperty); var isTargetWeakOrOwned = targetType != null && (conventionModel.HasEntityTypeWithDefiningNavigation(targetType) || conventionModel.IsOwned(targetType)); if (targetType?.IsValidEntityType() == true && (isTargetWeakOrOwned || conventionModel.FindEntityType(targetType) != null || targetType.GetRuntimeProperties().Any(p => p.IsCandidateProperty()))) { // ReSharper disable CheckForReferenceEqualityInstead.1 // ReSharper disable CheckForReferenceEqualityInstead.3 if ((!entityType.IsKeyless || targetSequenceType == null) && entityType.GetDerivedTypes().All( dt => dt.GetDeclaredNavigations().FirstOrDefault(n => n.Name == actualProperty.GetSimpleMemberName()) == null) && (!isTargetWeakOrOwned || (!targetType.Equals(entityType.ClrType) && (!entityType.IsInOwnershipPath(targetType) || (entityType.FindOwnership().PrincipalEntityType.ClrType.Equals(targetType) && targetSequenceType == null)) && (!entityType.IsInDefinitionPath(targetType) || (entityType.DefiningEntityType.ClrType.Equals(targetType) && targetSequenceType == null))))) { if (conventionModel.IsOwned(entityType.ClrType) && conventionModel.IsOwned(targetType)) { throw new InvalidOperationException( CoreStrings.AmbiguousOwnedNavigation(entityType.DisplayName(), targetType.ShortDisplayName())); } throw new InvalidOperationException( CoreStrings.NavigationNotAdded( entityType.DisplayName(), actualProperty.Name, propertyType.ShortDisplayName())); } // ReSharper restore CheckForReferenceEqualityInstead.3 // ReSharper restore CheckForReferenceEqualityInstead.1 } else if (targetSequenceType == null && propertyType.GetTypeInfo().IsInterface || targetSequenceType?.GetTypeInfo().IsInterface == true) { throw new InvalidOperationException( CoreStrings.InterfacePropertyNotAdded( entityType.DisplayName(), actualProperty.Name, propertyType.ShortDisplayName())); } else { throw new InvalidOperationException( CoreStrings.PropertyNotAdded( entityType.DisplayName(), actualProperty.Name, propertyType.ShortDisplayName())); } } } }
/// <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 InternalModelBuilder Apply(InternalModelBuilder modelBuilder) { foreach (var entityType in modelBuilder.Metadata.GetEntityTypes()) { var unmappedProperty = entityType.GetProperties().FirstOrDefault( p => (!ConfigurationSource.Convention.Overrides(p.GetConfigurationSource()) || !p.IsShadowProperty) && !IsMappedPrimitiveProperty(p)); if (unmappedProperty != null) { throw new InvalidOperationException( CoreStrings.PropertyNotMapped( entityType.DisplayName(), unmappedProperty.Name, unmappedProperty.ClrType.ShortDisplayName())); } if (!entityType.HasClrType()) { continue; } var clrProperties = new HashSet <string>(StringComparer.Ordinal); clrProperties.UnionWith( entityType.GetRuntimeProperties().Values .Where(pi => pi.IsCandidateProperty()) .Select(pi => pi.GetSimpleMemberName())); clrProperties.ExceptWith(entityType.GetProperties().Select(p => p.Name)); clrProperties.ExceptWith(entityType.GetNavigations().Select(p => p.Name)); clrProperties.ExceptWith(entityType.GetServiceProperties().Select(p => p.Name)); clrProperties.RemoveWhere(p => entityType.Builder.IsIgnored(p, ConfigurationSource.Convention)); if (clrProperties.Count <= 0) { continue; } foreach (var clrProperty in clrProperties) { var actualProperty = entityType.GetRuntimeProperties()[clrProperty]; var propertyType = actualProperty.PropertyType; var targetSequenceType = propertyType.TryGetSequenceType(); if (modelBuilder.IsIgnored( modelBuilder.Metadata.GetDisplayName(propertyType), ConfigurationSource.Convention) || (targetSequenceType != null && modelBuilder.IsIgnored( modelBuilder.Metadata.GetDisplayName(targetSequenceType), ConfigurationSource.Convention))) { continue; } var targetType = FindCandidateNavigationPropertyType(actualProperty); var isTargetWeakOrOwned = targetType != null && (modelBuilder.Metadata.HasEntityTypeWithDefiningNavigation(targetType) || modelBuilder.Metadata.ShouldBeOwnedType(targetType)); if (targetType?.IsValidEntityType() == true && (isTargetWeakOrOwned || modelBuilder.Metadata.FindEntityType(targetType) != null || targetType.GetRuntimeProperties().Any(p => p.IsCandidateProperty()))) { // ReSharper disable CheckForReferenceEqualityInstead.1 // ReSharper disable CheckForReferenceEqualityInstead.3 if ((!entityType.IsQueryType || targetSequenceType == null) && entityType.GetDerivedTypes().All( dt => dt.FindDeclaredNavigation(actualProperty.GetSimpleMemberName()) == null) && (!isTargetWeakOrOwned || (!targetType.Equals(entityType.ClrType) && (!entityType.IsInOwnershipPath(targetType) || (entityType.FindOwnership().PrincipalEntityType.ClrType.Equals(targetType) && targetSequenceType == null)) && (!entityType.IsInDefinitionPath(targetType) || (entityType.DefiningEntityType.ClrType.Equals(targetType) && targetSequenceType == null))))) { if (modelBuilder.Metadata.ShouldBeOwnedType(entityType.ClrType) && modelBuilder.Metadata.ShouldBeOwnedType(targetType)) { throw new InvalidOperationException( CoreStrings.AmbiguousOwnedNavigation(entityType.DisplayName(), targetType.ShortDisplayName())); } throw new InvalidOperationException( CoreStrings.NavigationNotAdded( entityType.DisplayName(), actualProperty.Name, propertyType.ShortDisplayName())); } // ReSharper restore CheckForReferenceEqualityInstead.3 // ReSharper restore CheckForReferenceEqualityInstead.1 } else if (targetSequenceType == null && propertyType.GetTypeInfo().IsInterface || targetSequenceType?.GetTypeInfo().IsInterface == true) { throw new InvalidOperationException( CoreStrings.InterfacePropertyNotAdded( entityType.DisplayName(), actualProperty.Name, propertyType.ShortDisplayName())); } else { throw new InvalidOperationException( CoreStrings.PropertyNotAdded( entityType.DisplayName(), actualProperty.Name, propertyType.ShortDisplayName())); } } } return(modelBuilder); }
/// <summary> /// Validates property mappings. /// </summary> /// <param name="model">The model.</param> /// <param name="logger">The logger to use.</param> protected virtual void ValidatePropertyMapping( IModel model, IDiagnosticsLogger <DbLoggerCategory.Model.Validation> logger) { if (model is not IConventionModel conventionModel) { return; } foreach (var entityType in conventionModel.GetEntityTypes()) { var unmappedProperty = entityType.GetDeclaredProperties().FirstOrDefault( p => (!ConfigurationSource.Convention.Overrides(p.GetConfigurationSource()) // Use a better condition for non-persisted properties when issue #14121 is implemented || !p.IsImplicitlyCreated()) && p.FindTypeMapping() == null); if (unmappedProperty != null) { ThrowPropertyNotMappedException( (unmappedProperty.GetValueConverter()?.ProviderClrType ?? unmappedProperty.ClrType).ShortDisplayName(), entityType, unmappedProperty); } if (entityType.ClrType == Model.DefaultPropertyBagType) { continue; } var runtimeProperties = entityType.GetRuntimeProperties(); var clrProperties = new HashSet <string>(StringComparer.Ordinal); clrProperties.UnionWith( runtimeProperties.Values .Where(pi => pi.IsCandidateProperty(needsWrite: false)) .Select(pi => pi.GetSimpleMemberName())); clrProperties.ExceptWith( ((IEnumerable <IConventionPropertyBase>)entityType.GetProperties()) .Concat(entityType.GetNavigations()) .Concat(entityType.GetSkipNavigations()) .Concat(entityType.GetServiceProperties()).Select(p => p.Name)); if (entityType.IsPropertyBag) { clrProperties.ExceptWith(_dictionaryProperties); } if (clrProperties.Count <= 0) { continue; } foreach (var clrPropertyName in clrProperties) { if (entityType.FindIgnoredConfigurationSource(clrPropertyName) != null) { continue; } var clrProperty = runtimeProperties[clrPropertyName]; var propertyType = clrProperty.PropertyType; var targetSequenceType = propertyType.TryGetSequenceType(); if (conventionModel.FindIgnoredConfigurationSource(propertyType) != null || conventionModel.IsIgnoredType(propertyType) || (targetSequenceType != null && (conventionModel.FindIgnoredConfigurationSource(targetSequenceType) != null || conventionModel.IsIgnoredType(targetSequenceType)))) { continue; } var targetType = Dependencies.MemberClassifier.FindCandidateNavigationPropertyType( clrProperty, conventionModel, out var targetOwned); if (targetType == null && clrProperty.FindSetterProperty() == null) { continue; } if (targetType != null) { var targetShared = conventionModel.IsShared(targetType); targetOwned ??= IsOwned(targetType, conventionModel); // ReSharper disable CheckForReferenceEqualityInstead.1 // ReSharper disable CheckForReferenceEqualityInstead.3 if ((!entityType.IsKeyless || targetSequenceType == null) && entityType.GetDerivedTypes().All( dt => dt.GetDeclaredNavigations().FirstOrDefault(n => n.Name == clrProperty.GetSimpleMemberName()) == null) && (!(targetShared || targetOwned.Value) || !targetType.Equals(entityType.ClrType)) && (!entityType.IsInOwnershipPath(targetType) || targetSequenceType == null)) { if (entityType.IsOwned() && targetOwned.Value) { throw new InvalidOperationException( CoreStrings.AmbiguousOwnedNavigation( entityType.DisplayName() + "." + clrProperty.Name, targetType.ShortDisplayName())); } if (targetShared) { throw new InvalidOperationException( CoreStrings.NonConfiguredNavigationToSharedType(clrProperty.Name, entityType.DisplayName())); } throw new InvalidOperationException( CoreStrings.NavigationNotAdded( entityType.DisplayName(), clrProperty.Name, propertyType.ShortDisplayName())); } // ReSharper restore CheckForReferenceEqualityInstead.3 // ReSharper restore CheckForReferenceEqualityInstead.1 } else if (targetSequenceType == null && propertyType.IsInterface || targetSequenceType?.IsInterface == true) { throw new InvalidOperationException( CoreStrings.InterfacePropertyNotAdded( entityType.DisplayName(), clrProperty.Name, propertyType.ShortDisplayName())); } else { throw new InvalidOperationException( CoreStrings.PropertyNotAdded( entityType.DisplayName(), clrProperty.Name, propertyType.ShortDisplayName())); } } } }