将子属性与父属性进行比较?

时间:2016-04-03 10:52:09

标签: c# fluentvalidation

我有这两个班级:

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);

实施此类规则的正确方法是什么?

2 个答案:

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