首页 > 解决方案 > Fluent-API 的自定义 DataAnnotations

问题描述

对于我的 ef 核心应用程序,我创建了一些受DataAnnotations. 即我必须定义一个自定义属性,以确保其中IList至少有一个项目。

自定义ValidationAttribute

public class ListLengthAttribute : ValidationAttribute
{
    public int Min { get; set; }
    public int Max { get; set; }

    public ListLengthAttribute()
    {
        Min = 0;
        Max = int.MaxValue;
    }

    public override bool IsValid(object value)
    {
        IList listValue = value as IList;

        if (listValue != null)
        {
            int listLength = listValue.Count;
            return listLength >= Min && listLength <= Max;
        }

        return false;
    }
}

生成的类可能类似于:

public class Dummy 
{
    [ListLength( Min = 1, ErrorMessage = "Each dummy should contain at least 1 foo." )]
    public List<Foo> Foos { get; set; }
}

现在我想完全摆脱DataAnnotations并使用(ef-core)Fluent-API。

ModelBuilder在我的课堂上使用时,有什么方法可以映射上述约束EntityFrameworkCore.DbContext

也许是这样的:

modelBuilder.Entity<Dummy>().Property( d => d.Foos ).MinLength(1);

标签: .net-coredata-annotationsef-fluent-apief-core-2.1

解决方案


您主要需要了解其中每一个的目的。数据注释用于定义模型的规则和约束。这些可用于服务器端、客户端数据库验证(用于相关部分)。自定义ValidationAttribute可用于服务器端验证。

Fluent API 纯粹用于转换为数据库配置。MaxLength(n)只有在客户端、服务器端和数据库端有直接含义的属性( varchar(n))。因此,这些属性在 fluent API 中确实有直接的替代品。但是,EF 不会自动理解您的自定义验证在数据库中的含义。例如,在您的情况下,当最大长度为 1 时,验证似乎被转换为一对一关系。因此,对于这个感知示例,您可以在 fluent API 中设置一对一。在这种情况下,EF 无法检查代码并理解验证的意图。

对于最大长度和最小长度的所有其他值,没有可以在数据库中设置的映射配置。因此,fluent API 不能为其提供映射功能。如果您使用的数据库确实具有类似的功能,您可以查看其 EF 库的文档以了解映射功能。

基于您想要摆脱数据注释的原因,您真正寻找的可能是流畅的验证。你可以查看这个库和这个 git repo,它在使用这个库时提供了模型的干净实现示例。


推荐阅读