FluentValidation中字符串拼接值的重复校验实现咨询
FluentValidation实现双字段拼接重复校验方案
先修正你代码里的几个核心问题:
- 字符串拼接不能用
&&(这是逻辑与运算符),得用+或String.Concat来拼接Name和Surname Must方法使用有误,你要校验的是拼接后的值是否重复,不是单个Name字段,且需要对比已存在的记录集合concatnatedvalue方法的命名、返回值和实际逻辑不匹配,它应该生成拼接字符串而非返回布尔值
正确实现思路
要做拼接值的重复校验,核心是让Validator能获取到已有的所有记录,然后对比当前实体的拼接值是否在已有记录中存在(如果是编辑场景,需排除自身)。
完整代码示例
public class RecordValidator : AbstractValidator<RecordRow> { // 注入已存在的记录集合,用于重复校验 private readonly IEnumerable<RecordRow> _existingRecords; public RecordValidator(IEnumerable<RecordRow> existingRecords) { _existingRecords = existingRecords ?? Enumerable.Empty<RecordRow>(); // 校验拼接后的Name+Surname是否重复 RuleFor(x => x) .Must(BeUniqueConcatenatedValue) .WithMessage("Name和Surname组合已存在,请勿重复提交"); } // 拼接字段并检查是否重复 private bool BeUniqueConcatenatedValue(RecordRow currentRow) { // 生成拼接值,建议加分隔符避免歧义(比如"张三"+"李四"和"张"+"三李四"混淆) string concatenated = $"{currentRow.Name}_{currentRow.Surname}"; // 也可用String.Concat提升效率:String.Concat(currentRow.Name, "_", currentRow.Surname) // 普通新增场景:检查已有记录是否存在相同拼接值 // return !_existingRecords.Any(r => $"{r.Name}_{r.Surname}" == concatenated); // 编辑场景:需排除当前记录自身(通过唯一标识如Id判断) return !_existingRecords.Any(r => r.Id != currentRow.Id && $"{r.Name}_{r.Surname}" == concatenated); } }
关键优化说明
- 注入已有记录:通过构造函数传入已存在的
RecordRow集合,Validator才能完成重复值对比 - 避免拼接歧义:添加分隔符(比如下划线)能防止不同字段组合产生相同拼接结果的问题
- 兼容编辑场景:如果是修改已有记录,一定要在判断中排除当前记录的自身数据
- 性能优化(可选):如果记录数量多,可提前把已有拼接值存入
HashSet<string>,提升检查效率:
// 在构造函数中初始化HashSet private readonly HashSet<string> _existingConcatenatedValues; public RecordValidator(IEnumerable<RecordRow> existingRecords) { var records = existingRecords ?? Enumerable.Empty<RecordRow>(); _existingConcatenatedValues = new HashSet<string>(records.Select(r => $"{r.Name}_{r.Surname}")); RuleFor(x => x) .Must(BeUniqueConcatenatedValue) .WithMessage("Name和Surname组合已存在,请勿重复提交"); } private bool BeUniqueConcatenatedValue(RecordRow currentRow) { string concatenated = $"{currentRow.Name}_{currentRow.Surname}"; // 编辑场景需先移除当前记录的拼接值再检查 if (currentRow.Id != default) _existingConcatenatedValues.Remove(concatenated); return !_existingConcatenatedValues.Contains(concatenated); }
内容的提问来源于stack exchange,提问作者Dev
相关产品推荐
相关产品推荐

