private static void CheckIgnoredProperties( IndexAttribute indexAttribute, IConventionEntityType entityType) { foreach (var propertyName in indexAttribute.PropertyNames) { if (entityType.Builder.IsIgnored(propertyName, fromDataAnnotation: true)) { if (indexAttribute.Name == null) { throw new InvalidOperationException( CoreStrings.UnnamedIndexDefinedOnIgnoredProperty( entityType.DisplayName(), indexAttribute.PropertyNames.Format(), propertyName)); } throw new InvalidOperationException( CoreStrings.NamedIndexDefinedOnIgnoredProperty( indexAttribute.Name, entityType.DisplayName(), indexAttribute.PropertyNames.Format(), propertyName)); } } }
private static void CheckMissingProperties( IndexAttribute indexAttribute, IConventionEntityType entityType, InvalidOperationException innerException) { foreach (var propertyName in indexAttribute.PropertyNames) { var property = entityType.FindProperty(propertyName); if (property == null) { if (indexAttribute.Name == null) { throw new InvalidOperationException( CoreStrings.UnnamedIndexDefinedOnNonExistentProperty( entityType.DisplayName(), indexAttribute.PropertyNames.Format(), propertyName), innerException); } throw new InvalidOperationException( CoreStrings.NamedIndexDefinedOnNonExistentProperty( indexAttribute.Name, entityType.DisplayName(), indexAttribute.PropertyNames.Format(), propertyName), innerException); } } }
private MemberInfo FindForeignKeyAttributeOnProperty(IConventionEntityType entityType, string navigationName) { if (string.IsNullOrWhiteSpace(navigationName) || !entityType.HasClrType()) { return(null); } MemberInfo candidateProperty = null; foreach (var memberInfo in entityType.GetRuntimeProperties().Values.Cast <MemberInfo>() .Concat(entityType.GetRuntimeFields().Values)) { if (entityType.Builder.IsIgnored(memberInfo.GetSimpleMemberName()) || !Attribute.IsDefined(memberInfo, typeof(ForeignKeyAttribute), inherit: true)) { continue; } var attribute = memberInfo.GetCustomAttribute <ForeignKeyAttribute>(inherit: true); if (attribute.Name != navigationName || (memberInfo is PropertyInfo propertyInfo && (FindCandidateNavigationPropertyType(propertyInfo) != null || IsNavigationToSharedType(entityType.Model, propertyInfo)))) { continue; } if (candidateProperty != null) { throw new InvalidOperationException( CoreStrings.CompositeFkOnProperty(navigationName, entityType.DisplayName())); } candidateProperty = memberInfo; } if (candidateProperty != null) { var fkAttributeOnNavigation = GetForeignKeyAttribute(entityType, navigationName); if (fkAttributeOnNavigation != null && fkAttributeOnNavigation.Name != candidateProperty.GetSimpleMemberName()) { throw new InvalidOperationException( CoreStrings.FkAttributeOnPropertyNavigationMismatch( candidateProperty.Name, navigationName, entityType.DisplayName())); } } return(candidateProperty); }
private MemberInfo?FindForeignKeyAttributeOnProperty(IConventionEntityType entityType, MemberInfo?navigation) { if (navigation == null) { return(null); } var navigationName = navigation.GetSimpleMemberName(); MemberInfo?candidateProperty = null; foreach (var memberInfo in entityType.GetRuntimeProperties().Values.Cast <MemberInfo>() .Concat(entityType.GetRuntimeFields().Values)) { if (!Attribute.IsDefined(memberInfo, typeof(ForeignKeyAttribute), inherit: true) || !entityType.Builder.CanHaveProperty(memberInfo, fromDataAnnotation: true)) { continue; } var attribute = memberInfo.GetCustomAttribute <ForeignKeyAttribute>(inherit: true) !; if (attribute.Name != navigationName || (memberInfo is PropertyInfo propertyInfo && IsNavigationCandidate(propertyInfo, entityType))) { continue; } if (candidateProperty != null) { throw new InvalidOperationException( CoreStrings.CompositeFkOnProperty(navigationName, entityType.DisplayName())); } candidateProperty = memberInfo; } if (candidateProperty != null) { var fkAttributeOnNavigation = GetAttribute <ForeignKeyAttribute>(navigation); if (fkAttributeOnNavigation != null && fkAttributeOnNavigation.Name != candidateProperty.GetSimpleMemberName()) { throw new InvalidOperationException( CoreStrings.FkAttributeOnPropertyNavigationMismatch( candidateProperty.Name, navigationName, entityType.DisplayName())); } } return(candidateProperty); }
private static bool CheckPrimaryKeyAttributeAndEnsurePrimaryKey( IConventionEntityType entityType, bool shouldThrow) { var primaryKeyAttribute = entityType.ClrType.GetCustomAttributes <PrimaryKeyAttribute>(inherit: true).FirstOrDefault(); if (primaryKeyAttribute == null) { return(false); } if (Attribute.IsDefined(entityType.ClrType, typeof(KeylessAttribute))) { throw new InvalidOperationException( CoreStrings.ConflictingKeylessAndPrimaryKeyAttributes(entityType.DisplayName())); } IConventionKeyBuilder?keyBuilder; if (!shouldThrow) { var keyProperties = new List <IConventionProperty>(); foreach (var propertyName in primaryKeyAttribute.PropertyNames) { var property = entityType.FindProperty(propertyName); if (property == null) { return(true); } keyProperties.Add(property); } keyBuilder = entityType.Builder.PrimaryKey(keyProperties, fromDataAnnotation: true); } else { try { // Using the PrimaryKey(propertyNames) overload gives us a chance to create a missing property // e.g. if the CLR property existed but was non-public. keyBuilder = entityType.Builder.PrimaryKey(primaryKeyAttribute.PropertyNames, fromDataAnnotation: true); } catch (InvalidOperationException exception) { CheckMissingProperties(entityType, primaryKeyAttribute, exception); throw; } } if (keyBuilder == null && shouldThrow) { CheckIgnoredProperties(entityType, primaryKeyAttribute); } return(true); }
/// <summary> /// Throws an <see cref="InvalidOperationException" /> with a message containing provider-specific information, when /// available, indicating possible reasons why the property cannot be mapped. /// </summary> /// <param name="propertyType">The property CLR type.</param> /// <param name="entityType">The entity type.</param> /// <param name="unmappedProperty">The property.</param> protected virtual void ThrowPropertyNotMappedException( string propertyType, IConventionEntityType entityType, IConventionProperty unmappedProperty) => throw new InvalidOperationException( CoreStrings.PropertyNotMapped( propertyType, entityType.DisplayName(), unmappedProperty.Name));
private static void CheckIgnoredProperties(IConventionEntityType entityType, PrimaryKeyAttribute primaryKeyAttribute) { foreach (var propertyName in primaryKeyAttribute.PropertyNames) { if (entityType.Builder.IsIgnored(propertyName, fromDataAnnotation: true)) { throw new InvalidOperationException( CoreStrings.PrimaryKeyDefinedOnIgnoredProperty( entityType.DisplayName(), propertyName)); } } }
/// <summary> /// Adds a property backed by and indexer to this entity type. /// </summary> /// <param name="entityType"> The entity type. </param> /// <param name="name"> The name of the property to add. </param> /// <param name="propertyType"> The type of value the property will hold. </param> /// <param name="setTypeConfigurationSource"> Indicates whether the type configuration source should be set. </param> /// <param name="fromDataAnnotation"> Indicates whether the configuration was specified using a data annotation. </param> /// <returns> The newly created property. </returns> public static IConventionProperty AddIndexerProperty( [NotNull] this IConventionEntityType entityType, [NotNull] string name, [NotNull] Type propertyType, bool setTypeConfigurationSource = true, bool fromDataAnnotation = false) { Check.NotNull(entityType, nameof(entityType)); var indexerPropertyInfo = entityType.FindIndexerPropertyInfo(); if (indexerPropertyInfo == null) { throw new InvalidOperationException( CoreStrings.NonIndexerEntityType(name, entityType.DisplayName(), typeof(string).ShortDisplayName())); } return(entityType.AddProperty(name, propertyType, indexerPropertyInfo, setTypeConfigurationSource, fromDataAnnotation)); }
private static void CheckMissingProperties( IConventionEntityType entityType, PrimaryKeyAttribute primaryKeyAttribute, InvalidOperationException exception) { foreach (var propertyName in primaryKeyAttribute.PropertyNames) { var property = entityType.FindProperty(propertyName); if (property == null) { throw new InvalidOperationException( CoreStrings.PrimaryKeyDefinedOnNonExistentProperty( entityType.DisplayName(), primaryKeyAttribute.PropertyNames.Format(), propertyName), exception); } } }