如何修改FluentValidation验证器实现GroupCode+GroupRec复合键唯一性验证?
解决方案
你当前的代码是分别验证GroupCode和GroupRec的单独唯一性,但实际需要的是两者组合起来的复合键唯一性。以下是具体修改步骤:
- 移除无效的单字段唯一性验证:删除
RuleFor(v => v.GroupCode)和RuleFor(v => v.GroupRec)中的.MustAsync(BeUniqueName)调用,因为它们不符合复合键的验证需求。 - 新增复合键验证规则:添加针对整个命令对象的验证规则,调用专门的异步方法检查复合键唯一性。
- 实现复合键验证逻辑:编写能同时读取
GroupCode和GroupRec的验证方法,查询数据库是否存在同时匹配这两个值的记录。
修改后的完整代码示例:
private readonly IApplicationDBContext _context; public CreateGroupingCommandValidator(IApplicationDBContext context) { _context = context; RuleFor(v => v.GroupCode) .MaximumLength(50).WithMessage("Maximum length is 50.") .NotEmpty().WithMessage("Required."); RuleFor(v => v.GroupRec) .MaximumLength(50).WithMessage("Maximum length is 50.") .NotEmpty().WithMessage("Required."); RuleFor(v => v.oDescription) .MaximumLength(50).WithMessage("Maximum length is 50."); // 新增复合键唯一性验证规则 RuleFor(v => v) .MustAsync(BeUniqueCompositeKey) .WithMessage("The combination of GroupCode and GroupRec already exists."); } // 复合键唯一性验证方法 private async Task<bool> BeUniqueCompositeKey(CreateGroupingCommand command, CancellationToken cancellationToken) { // 使用AnyAsync更高效:找到匹配记录立即返回,无需遍历全表 return !await _context.Mrekcs.AnyAsync( x => x.GroupCode == command.GroupCode && x.GroupRec == command.GroupRec, cancellationToken); }
紧凑写法(无需单独定义方法)
如果不想单独写验证方法,也可以直接在MustAsync中使用匿名函数:
// 替换上述的RuleFor(v => v)和BeUniqueCompositeKey方法 RuleFor(v => new { v.GroupCode, v.GroupRec }) .MustAsync(async (composite, cancellationToken) => !await _context.Mrekcs.AnyAsync( x => x.GroupCode == composite.GroupCode && x.GroupRec == composite.GroupRec, cancellationToken)) .WithMessage("The combination of GroupCode and GroupRec already exists.");
核心逻辑说明:
- 复合键唯一性的判定标准是:数据库中不存在
GroupCode和GroupRec同时与当前请求值匹配的记录。 - 使用
AnyAsync比AllAsync性能更优,因为一旦找到匹配记录就会终止查询。
内容的提问来源于stack exchange,提问作者Haminteu
相关产品推荐
相关产品推荐

