FluentValidation: Сравнение значения с совокупностью значений? - PullRequest
0 голосов
/ 19 февраля 2019

Я нахожу FluentValidation простым, когда создаю простые правила для свойств для одного класса, но как только мне нужно сравнить значения из коллекций (например, свойство List<T>), он становится сверх волосатым.Предположим, что следующие два минимальных класса:

public class PurchaseOrder
{
    public List<LineItem> LineItems { get; set; }
    public decimal Total { get; set; }

    public PurchaseOrder()
    {
        LineItems = new List<LineItem>();
    }
}

public class LineItem
{
    public decimal Price { get; set; }
}

И этот класс:

class Program
{
    static void Main(string[] args)
    {
        PurchaseOrder order = new PurchaseOrder();
        order.LineItems.Add(new LineItem() { Price = 12m });
        order.LineItems.Add(new LineItem() { Price = 14m });
        order.Total = 26m;

        PurchaseOrderValidator validator = new PurchaseOrderValidator();
        ValidationResult result = validator.Validate(order);
    }
}

Как будет выглядеть PurchaseOrderValidator, чтобы убедиться, что сумма всех LineItem.Price равна PurchaseOrder.Total?Вот заглушка (хотя я не уверен, что Must() это путь):

public class PurchaseOrderValidator : AbstractValidator<PurchaseOrder>
{
    public PurchaseOrderValidator()
    {
        RuleFor(x => x.Total).Must(MatchSumOfLineItems);
    }

    private bool MatchSumOfLineItems(decimal arg)
    {
        return true;
    }
}

Ответы [ 2 ]

0 голосов
/ 19 февраля 2019

Почему бы не использовать .Equal()

public class PurchaseOrderValidator : AbstractValidator<PurchaseOrder>
{
    public PurchaseOrderValidator()
    {
        RuleFor(x => x.Total).Equal(x => x.LineItems.Sum(item => item.Price));
    }
}

0 голосов
/ 19 февраля 2019

Просто создайте метод проверки, который принимает PurchaseOrder в качестве ввода, и делайте с ним все, что вы хотите

public class PurchaseOrderValidator : AbstractValidator<PurchaseOrder>
{
    public PurchaseOrderValidator()
    {
        RuleFor(x => x).Must(MatchSumOfLineItems);
    }

    private bool MatchSumOfLineItems(PurchaseOrder arg)
    {
        return arg.Total == arg.LineItems.Sum(i => i.Price);
    }
}

или если вы хотите добавить проверку специально для Total свойства, вы можете использовать другое Mustперегрузка принимает Func<decimal, PurchaseOrder, bool>

public class PurchaseOrderValidator : AbstractValidator<PurchaseOrder>
{
    public PurchaseOrderValidator()
    {
        RuleFor(x => x.Total).Must(MatchSumOfLineItems);
    }

    private bool MatchSumOfLineItems(PurchaseOrder order, decimal sum)
    {
        return sum == order.LineItems.Sum(i => i.Price);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...