我有这两个班级:
public class Master
{
public int? TotalAmount;
public ICollection<Detail> Details;
}
public class Detail
{
public int Amount;
}
我正在尝试创建规则,以便详细信息集合的总金额等于主人的总金额属性。
我正在尝试以下规则,但我无法访问主人的属性:
RuleFor(x => x.Details)
.Must(coll => coll.Sum(item => item.Amount) == x.TotalAmount)
.When(x => x.Details != null)
.When(x => x.TotalAmount.HasValue);
实施此类规则的正确方法是什么?
答案 0 :(得分:1)
你可以使用Must的另一个重载,如下所示:
RuleFor(x => x.Details)
.Must((master, details, ctx) => master.TotalAmount == details.Sum(r => r.Amount))
.When(x => x.Details != null)
.When(x => x.TotalAmount.HasValue);
但是请注意,正如评论中已经指出的那样,您不应该使用验证来进行一致性检查。你只有一个数据(详细数量总和)。所以为什么不这样做:
public class Master {
public int? TotalAmount
{
get
{
if (Details == null)
return null;
return Details.Sum(c => c.Amount);
}
}
public ICollection<Detail> Details;
}
答案 1 :(得分:0)
我发现实现此类验证的最佳方法是使用如下自定义验证器方法:
public class Validator : AbstractValidator<Master>
{
public Validator()
{
RuleFor(master => master)
.Must(CalculateSumCorrectly)
.When(master => master.Details != null)
.When(master => master.TotalAmount.HasValue);
}
private bool CalculateSumCorrectly(Master arg)
{
return arg.TotalAmount == arg.Details.Sum(detail => detail.Amount);
}
}
请注意,此处的规则被描述为应用于整个主对象; RuleFor(master => master)
。这是允许您访问这两个属性的技巧。