Аннотации данных, не переопределяющие свойства 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)");