Esempio n. 1
0
        /// <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 void AddKeyConfiguration([NotNull] EntityConfiguration entityConfiguration)
        {
            Check.NotNull(entityConfiguration, nameof(entityConfiguration));

            var entityType = (EntityType)entityConfiguration.EntityType;

            foreach (var key in entityType.GetKeys())
            {
                if (key == null ||
                    key.Properties.Count == 0)
                {
                    continue;
                }

                var conventionKeyProperties =
                    _keyDiscoveryConvention.DiscoverKeyProperties(entityType, entityType.GetProperties().ToList());
                if (conventionKeyProperties != null &&
                    key.Properties.OrderBy(p => p.Name).SequenceEqual(conventionKeyProperties.OrderBy(p => p.Name)))
                {
                    continue;
                }

                if (key.IsPrimaryKey())
                {
                    var keyFluentApi = _configurationFactory
                                       .CreateKeyFluentApiConfiguration("e", key);

                    if (key.Properties.Count == 1 &&
                        key.Relational().Name ==
                        RelationalKeyAnnotations
                        .GetDefaultKeyName(
                            entityType.Relational().TableName,
                            true,     /* is primary key */
                            key.Properties.Select(p => p.Relational().ColumnName)))
                    {
                        keyFluentApi.HasAttributeEquivalent = true;

                        var propertyConfiguration =
                            entityConfiguration.GetOrAddPropertyConfiguration(
                                entityConfiguration, key.Properties.First());
                        propertyConfiguration.AttributeConfigurations.Add(
                            _configurationFactory.CreateAttributeConfiguration(nameof(KeyAttribute)));
                    }

                    entityConfiguration.FluentApiConfigurations.Add(keyFluentApi);
                }
            }
        }
Esempio n. 2
0
        protected virtual IndexBuilder VisitIndex([NotNull] EntityTypeBuilder builder, [NotNull] IndexModel index)
        {
            Check.NotNull(builder, nameof(builder));
            Check.NotNull(index, nameof(index));

            var indexColumns = index.IndexColumns
                               .OrderBy(ic => ic.Ordinal)
                               .Select(ic => ic.Column).ToList();
            var unmappedColumns = indexColumns
                                  .Where(c => _unmappedColumns.Contains(c))
                                  .Select(c => c.Name).ToList();

            if (unmappedColumns.Any())
            {
                Logger.LogWarning(
                    RelationalDesignEventId.IndexColumnsNotMappedWarning,
                    () => RelationalDesignStrings.UnableToScaffoldIndexMissingProperty(
                        index.Name,
                        string.Join(CultureInfo.CurrentCulture.TextInfo.ListSeparator, unmappedColumns)));
                return(null);
            }

            var columnNames   = indexColumns.Select(c => c.Name);
            var propertyNames = indexColumns.Select(GetPropertyName).ToArray();

            if (index.Table != null)
            {
                var primaryKeyColumns = index.Table.Columns
                                        .Where(c => c.PrimaryKeyOrdinal.HasValue)
                                        .OrderBy(c => c.PrimaryKeyOrdinal);
                if (columnNames.SequenceEqual(primaryKeyColumns.Select(c => c.Name)) && index.Filter == null)
                {
                    // index is supporting the primary key. So there is no need for
                    // an extra index in the model. But if the index name does not
                    // match what would be produced by default then need to call
                    // HasName() on the primary key.
                    if (index.Name !=
                        RelationalKeyAnnotations
                        .GetDefaultKeyName(
                            index.Table.Name,
                            true,     /* is primary key */
                            primaryKeyColumns.Select(GetPropertyName)))
                    {
                        builder.HasKey(propertyNames).HasName(index.Name);
                    }
                    return(null);
                }
            }

            var indexBuilder = builder.HasIndex(propertyNames)
                               .IsUnique(index.IsUnique);

            if (index.Filter != null)
            {
                indexBuilder.HasFilter(index.Filter);
            }

            if (!string.IsNullOrEmpty(index.Name))
            {
                indexBuilder.HasName(index.Name);
            }

            if (index.IsUnique)
            {
                var keyBuilder = builder.HasAlternateKey(propertyNames);
                if (!string.IsNullOrEmpty(index.Name))
                {
                    keyBuilder.HasName(index.Name);
                }
            }

            return(indexBuilder);
        }
Esempio n. 3
0
        protected virtual IndexBuilder VisitIndex([NotNull] EntityTypeBuilder builder, [NotNull] IndexModel index)
        {
            Check.NotNull(builder, nameof(builder));
            Check.NotNull(index, nameof(index));

            var propertyNames = index.IndexColumns
                                .OrderBy(ic => ic.Ordinal)
                                .Select(ic => GetPropertyName(ic.Column))
                                .ToArray();

            if (propertyNames.Count(p => builder.Metadata.FindProperty(p) != null) != propertyNames.Length)
            {
                Logger.LogWarning(RelationalDesignStrings.UnableToScaffoldIndexMissingProperty(index.Name));
                return(null);
            }

            var columnNames = index.IndexColumns
                              .OrderBy(ic => ic.Ordinal)
                              .Select(ic => ic.Column.Name);

            if (index.Table != null)
            {
                var primaryKeyColumns = index.Table.Columns
                                        .Where(c => c.PrimaryKeyOrdinal.HasValue)
                                        .OrderBy(c => c.PrimaryKeyOrdinal);
                if (columnNames.SequenceEqual(primaryKeyColumns.Select(c => c.Name)))
                {
                    // index is supporting the primary key. So there is no need for
                    // an extra index in the model. But if the index name does not
                    // match what would be produced by default then need to call
                    // HasName() on the primary key.
                    if (index.Name !=
                        RelationalKeyAnnotations
                        .GetDefaultKeyName(
                            index.Table.Name,
                            true,     /* is primary key */
                            primaryKeyColumns.Select(c => GetPropertyName(c))))
                    {
                        builder.HasKey(propertyNames.ToArray()).HasName(index.Name);
                    }
                    return(null);
                }
            }

            var indexBuilder = builder.HasIndex(propertyNames)
                               .IsUnique(index.IsUnique);

            if (!string.IsNullOrEmpty(index.Name))
            {
                indexBuilder.HasName(index.Name);
            }

            if (index.IsUnique)
            {
                var keyBuilder = builder.HasAlternateKey(propertyNames);
                if (!string.IsNullOrEmpty(index.Name))
                {
                    keyBuilder.HasName(index.Name);
                }
            }

            return(indexBuilder);
        }