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);
        }
Esempio n. 4
0
    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);
    }
Esempio n. 5
0
    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);
    }
Esempio n. 6
0
 /// <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));
Esempio n. 7
0
 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));
        }
Esempio n. 9
0
 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);
         }
     }
 }