如何为所有 Code First Required 字符串设置 AllowEmptyStrings?

How can I set AllowEmptyStrings for all Code First Required strings?

我可以用这个属性装饰模型中的单个字符串 -

[Required(AllowEmptyStrings= true)]

如何对 OnModelCreating 中的所有必需字符串执行此操作?

注意我不想像这样关闭验证 -

mDbContext.Configuration.ValidateOnSaveEnabled = false;

不幸的是,我认为答案是你不能。

在 FluentAPI 中,您可以使用将适用于整个上下文的自定义约定:

//All strings are required
modelBuilder.Properties<string>()
    .Configure(p => p.IsRequired());

//All strings named "Foo" are required and have a maximum length
modelBuilder.Properties<string>()
    .Where(p => p.Name == "Foo")
    .Configure(p => p.IsRequired().HasMaxLength(256));

//All strings with a "Required" attribute have a maximum length:
modelBuilder.Properties<string>()
    .Where(p => p.CustomAttributes
                .Where(a => a.AttributeType == typeof(RequiredAttribute))
                .Any())
    .Configure(p => p.HasMaxLength(256));

问题是 Fluent API 无法访问 "AllowEmptyStrings" 属性。它可能是在设计时考虑到配置数据库的。检查空字符串是通常在数据进入数据库之前完成的验证

参考:Custom Conventions

或者,您可以子类化 System.ComponentModel.DataAnnotations.RequiredAttribute,并覆盖 IsValid() 方法。 根据来源:https://github.com/microsoft/referencesource/blob/master/System.ComponentModel.DataAnnotations/DataAnnotations/RequiredAttribute.cs

理想情况下,您会为 "best practices" 使用不同的属性(并删除 [Required]),但在我的情况下,我正在与设计师一起生成模型,所以我决定公开[RequiredAttribute] 字面上在命名空间中,因此导致我的模型使用我自己的 "Required" 属性而不是 EF 的。在全球范围内发挥魅力。

虽然我同意上面 Colin 的观点 - 这不是 "great practice"(根据 EF 设计),但我也不会称它为 "bad practice"。我可能会称之为 "unsafe practice"。 EF 的手很重,我更喜欢用我自己的方式管理我的数据库,而不是他们的。
主要问题是 <TKey>string 类型。像默认的 AspNetUsers (等)。因此不安全。
如果您可以保证您的代码被正确使用,那么这不是问题。

比如..

(note: I chose not to override IsValid, as the below is far cleaner than an override)

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
public class RequiredAttribute : System.ComponentModel.DataAnnotations.RequiredAttribute {
    public RequiredAttribute() : base() {
        AllowEmptyStrings = true;
    }
}

如果我有选择的话,我可能会专门针对字符串使用 类型检查来改进这一点,但到那时,您最好用适当的项目替换所有地方的 [Required]
这就是我将在长 运行.. 中做的事情。在我特别需要它的字段上使用设计器中的自定义属性。但是根据你的问题,上面的答案。