【问题标题】:Data Annotations not overriding configurationBuilder properties数据注释不覆盖 configurationBuilder 属性
【发布时间】:2022-11-02 05:10:12
【问题描述】:

在我的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)

【问题讨论】:

  • 根据this MS docs article (for EF Core 6),我怕你不能您还可以将属性(称为数据注释)应用于您的类和属性。数据注释将覆盖约定,但会被 Fluent API 配置覆盖。- 不确定 EF Core 中是否有任何变化7在这方面
  • 配置生成器是否考虑了流畅的 API?
  • 也许HasColumnType
  • 因此,我查看了您的 likk,他们在抱怨与 configurationbuilde 不同的 modlebuilder(据我所知)。所以不知道这是否适用。我将发布到 git 实验室寻求帮助
  • 是的,使用ConfigurationBuilder流畅的 API

标签: entity-framework-core ef-core-7.0


【解决方案1】:

你在这里使用Pre-convention configuration。当前的文档没有明确说明这种类型的配置如何与模型配置协作,即流畅的 API(配置类和OnModelCreating 覆盖)和数据注释,但它确实说

此配置在创建模型之前执行。

这表明模型配置推翻了它。是的,确实如此。

但是,在我的测试中,只有 fluent API 始终如一。数据注释很混乱(不仅在实体框架中)。例如,[StringLength(20)] 覆盖长度,[Unicode(true)] 覆盖不是覆盖varchar 数据类型和[Column(TypeName = "varchar(max)")](或[DataType("nvarchar(max)")])确实不是覆盖长度或数据类型。

意思是:总是使用 fluent API 对约定的异常进行建模:

modelBuilder.Entity<MyClass>()
    .Property(e => e.AffectedColumns)
    .HasColumnType("nvarchar(max)");

【讨论】:

    【解决方案2】:

    EFCore 7 引入了最终约定。看起来您正在寻找的部分在这里: Default length for all string properties

    您需要将您的约定放在新的 for v7 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);
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-25
      • 1970-01-01
      • 2017-05-08
      • 1970-01-01
      • 1970-01-01
      • 2012-02-03
      • 2011-12-08
      • 1970-01-01
      相关资源
      最近更新 更多