Fluent Validation报错排查:删除请求验证逻辑问题求助
首先,你的代码逻辑存在几个关键问题,导致无法正确验证删除规则,甚至会引发你提到的“Enumeration yielded no results”提示(虽然你说repositoryEntities不为空,但IQueryable对象本身不为空不代表数据库中有匹配数据,遍历它时才会执行查询,若数据库无匹配记录就会出现这个提示):
核心逻辑错误
循环判断逻辑完全颠倒:
你在遍历过程中,每次找到更高价格就更新最大值然后continue,直接跳过了后续的检查逻辑。只有遇到价格小于当前最大值的元素时,才会去检查要删除的实体价格是否等于最大值——这完全搞反了验证逻辑,我们需要验证的是要删除的实体是否属于该类型中价格最高的范畴,而非在遍历其他元素时做零散检查。缺少最终验证环节:
如果要删除的实体本身就是该类型价格最高的,遍历到它时会更新最大值然后continue,整个循环结束后不会做任何验证,相当于直接通过检查;但如果repositoryEntities中只有这一个最高价格的实体,循环结束后也没有确认步骤,逻辑存在漏洞。IQueryable延迟执行的误解:
_productRepository.Queryable返回的是IQueryable,它是延迟执行的——你判断repositoryEntities != null永远为true,因为IQueryable对象本身不会为null,只有执行查询(比如foreach、ToList())时才会去数据库取数据,若数据库无匹配记录,遍历就不会执行,进而出现“Enumeration yielded no results”的提示。
修复后的代码
我们可以简化逻辑,直接用LINQ方法获取该类型的最高价格,再对比要删除的实体价格,这样更清晰高效:
private void CanIDelete(DeleteProductRequest entity, CustomContext context) { // 获取该产品类型下未删除的所有实体 var repositoryEntities = _productRepository.Queryable .Where(s => s.TypeOfProductId.Equals(entity.TypeOfProductId) && !s.IsDeleted); // 先检查数据库中是否存在该类型的未删除产品 if (!repositoryEntities.Any()) { context.AddFailure("No available products of this type to delete"); return; } // 获取该类型产品的最高价格 var maxPrice = repositoryEntities.Max(s => s.Price); // 验证要删除的产品价格是否等于最高价格 if (entity.Price != maxPrice) { context.AddFailure("Deletion allowed only for one product 'with the biggest price' in database for each type of product"); return; } }
额外优化建议
如果业务允许同类型下存在多个相同最高价格的产品,或者需要更精准验证(避免价格相同导致的误删),可以通过对比实体ID来判断:
private void CanIDelete(DeleteProductRequest entity, CustomContext context) { var repositoryEntities = _productRepository.Queryable .Where(s => s.TypeOfProductId.Equals(entity.TypeOfProductId) && !s.IsDeleted); if (!repositoryEntities.Any()) { context.AddFailure("No available products of this type to delete"); return; } // 获取价格最高的实体(若有多个,取第一个,可根据业务调整规则) var highestPriceProduct = repositoryEntities.OrderByDescending(s => s.Price).First(); // 通过ID对比,确保要删除的是目标最高价格产品 if (entity.ProductId != highestPriceProduct.Id) { context.AddFailure("Deletion allowed only for the product with the biggest price in database for each type of product"); return; } }
这样就能准确验证要删除的是该类型中价格最高的实体,避免价格相同带来的误判问题。
内容的提问来源于stack exchange,提问作者mattplpl

