比较 child 属性 和 parent 属性?

Compare child property with parent property?

我有这两个 类:

public class Master
{
    public int? TotalAmount;
    public ICollection<Detail> Details;
}

public class Detail
{
    public int Amount;
}

我正在尝试创建一个规则,使详细信息集合的总金额等于主数据集的总金额属性。

我正在尝试以下规则,但我无法访问 master 的 属性:

RuleFor(x => x.Details)
    .Must(coll => coll.Sum(item => item.Amount) == x.TotalAmount)
    .When(x => x.Details != null)
    .When(x => x.TotalAmount.HasValue);

执行这种规则的正确方法是什么?

我发现实现此类验证的最佳方法是使用如下自定义验证器方法:

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)。这是允许您访问这两个属性的技巧。

您可以只使用 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;
}