EF Core如何进行数据验证 EF Core Validation数据验证方法

来源:这里教程网 时间:2026-02-21 17:36:22 作者:

用数据注解做基础验证

这是最常用也最轻量的方式,直接在实体类属性上加特性,EF Core会在 SaveChanges() 时自动触发验证。不需要额外配置,只要引用 System.ComponentModel.DataAnnotations 命名空间即可。

常见注解包括:

[Required]:字段不能为空(会生成 NOT NULL 约束) [StringLength(50)]:限制字符串最大长度 [Range(18, 120)]:数值范围检查 [EmailAddress][Url]:格式校验(仅验证格式,不发请求) [RegularExpression(@"^\d{3}-\d{2}-\d{4}$")]:自定义正则匹配

注意:这些注解只在应用层生效,不会自动同步到数据库约束,如需双重保障,得配合迁移脚本手动添加 CHECK 或 UNIQUE 约束。

实现 IValidatableObject 做跨字段验证

当单个字段的规则不够用,比如“结束时间不能早于开始时间”,就得靠接口级验证。让实体类实现 IValidatableObject,重写 Validate 方法:

public class Order : IValidatableObject
{
    public DateTime StartDate { get; set; }
    public DateTime? EndDate { get; set; }
    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (EndDate.HasValue && EndDate.Value < StartDate)
            yield return new ValidationResult("结束时间不能早于开始时间", new[] { nameof(EndDate) });
    }
}

这个方法会在 SaveChanges 前被调用,支持返回多个错误,也能精准指定出错字段。

手动触发验证获取详细错误

有时你不想等到 SaveChanges 才知道错在哪,比如前端提交前想预检。可以用 .NET 自带的 Validator 类主动验证对象:

var context = new AppDbContext();
var user = new User { Name = "TooLongNameForFive" };
var validationContext = new ValidationContext(user);
var results = new List<ValidationResult>();
bool isValid = Validator.TryValidateObject(user, validationContext, results, true);
if (!isValid)
{
    foreach (var error in results)
    {
        Console.WriteLine(error.ErrorMessage);
    }
}

参数 true 表示验证所有属性(含私有和嵌套对象),适合调试或 API 入口校验。

结合 FluentValidation 做更灵活的业务验证

如果项目中验证逻辑复杂、需要依赖服务(如查数据库判断用户名是否已存在),内置方式就力不从心了。这时推荐引入 FluentValidation

单独定义验证器类,与实体解耦 支持异步验证、条件验证、本地化错误消息 可无缝集成 ASP.NET Core 的模型绑定和中间件

例如:

public class UserValidator : AbstractValidator<User>
{
    public UserValidator()
    {
        RuleFor(x => x.Email).NotEmpty().EmailAddress();
        RuleFor(x => x.Name).MustAsync(async (user, name, ct) =>
            !await IsNameTaken(name)).WithMessage("用户名已被占用");
    }
}

注册后,EF Core 不会自动调用它,但你可以包装 SaveChanges 或在仓储层统一拦截处理。

基本上就这些。核心是分清场景:简单字段规则用 Data Annotations;跨字段逻辑用 IValidatableObject;复杂业务或需服务参与时选 FluentValidation。数据库约束作为最后一道防线,建议手动补全。

相关推荐

热文推荐