Аннотации данных, не переопределяющие свойства configurationBuilder

В моемDbContext, я устанавливаю все строки вvarchar(250), но у меня есть несколько строк, помеченных какvarchar(max)". После создания моих миграций я вижу, что таблицы, помеченные как max, все еще создаются с максимальной длиной 250.

Как сделать так, чтобы мои аннотации данных переопределяли команду построителя конфигурации?

Конфигуратор:

      protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
{
    configurationBuilder.Properties<string>()
                        .HaveColumnType("varchar(250)")
                        .AreUnicode(false);
}

Сущность:

          [Column(TypeName = "varchar(max)")]
    public string? AffectedColumns { get; set; }

Что генерируется при миграции:

      AffectedColumns = table.Column<string>(type: "varchar(250)", unicode: false, nullable: true)

2 ответа

В EFCore 7 представлены соглашения о финализации. Похоже, что часть, которую вы ищете, находится здесь:Длина по умолчанию для всех строковых свойств.

Вам нужно поместить вашу конвенцию вProcessModelFinalizingметод. Явные конфигурации не переопределяются соглашением о завершении, поэтому ваши свойства, настроенные для varchar(max), должны быть в порядке.

      public class DiscriminatorLengthConvention2 : IModelFinalizingConvention
{
    public void ProcessModelFinalizing(IConventionModelBuilder modelBuilder, IConventionContext<IConventionModelBuilder> context)
    {
        foreach (var entityType in modelBuilder.Metadata.GetEntityTypes()
                     .Where(entityType => entityType.BaseType == null))
        {
            var discriminatorProperty = entityType.FindDiscriminatorProperty();
            if (discriminatorProperty != null
                && discriminatorProperty.ClrType == typeof(string))
            {
                discriminatorProperty.Builder.HasMaxLength(250);
            }
        }
    }
}

Здесь вы используете предварительную конфигурацию . Текущая документация явно не указывает, как этот тип конфигурации взаимодействует с конфигурацией модели, т. е. свободный API (классы конфигурации иOnModelCreatingпереопределяет) и аннотации данных, но он говорит

Эта конфигурация выполняется перед созданием модели.

Это указывает на то, что конфигурация модели отменяет ее. И да, это так.

Однако в моих тестах стабильно работает только свободный API. Аннотации данных запутаны (не только в Entity Framework). Например,[StringLength(20)]переопределяет длину,[Unicode(true)]не отменяет _varcharтип данных и[Column(TypeName = "varchar(max)")](или[DataType("nvarchar(max)")]) не переопределяет ни длину, ни тип данных.

Это означает: всегда используйте свободный API для моделирования исключений из соглашений:

      modelBuilder.Entity<MyClass>()
    .Property(e => e.AffectedColumns)
    .HasColumnType("nvarchar(max)");
Другие вопросы по тегам