Есть несколько способов сделать это.
Во-первых, FV doco предлагает начать с расширения Must
, чтобы делать подобные вещи. Для вашего случая вы бы сделали что-то подобное для вашего RoomValidator
RuleFor(o => o.Schedule).Must(schedule =>
{
if (schedule == null || !schedule.Any())
{
return true;
}
return schedule.All(item => !schedule.Where(x => !ReferenceEquals(item, x)).Any(x => x.Start < item.End && x.End > item.Start));
})
.WithMessage("Schedule can not have overlapping times.");
. Это выдаст вам одно сообщение об ошибке, если в списке расписания комнат будут совпадения даты и времени.
Если вы хотите больше контроля над сообщениями об ошибках; скажем, вы хотите распечатать, какие расписания перекрывались, используйте расширение Custom
.
RuleFor(o => o.Schedule).Custom((schedule, context) =>
{
if (schedule == null || !schedule.Any())
{
return;
}
foreach (var item in schedule)
{
var scheduleOverlapsAnotherSchedule = schedule.Where(x => !ReferenceEquals(item, x)).Any(x => x.Start < item.End && x.End > item.Start);
if (scheduleOverlapsAnotherSchedule)
{
context.AddFailure($"Schedule {item.Start.ToShortTimeString()}-{item.End.ToShortTimeString()} overlaps another schedule.");
}
}
});
Вы можете пойти дальше, переместив кишки чека в другой метод, чтобы упростить тест. читать или повторно использовать валидатор свойства, если вы делаете один и тот же вид проверки снова и снова. Я не буду описывать их здесь, так как это не то, о чем просили, однако они описаны в приведенной выше ссылке.
Рабочий пример вышеуказанных правил можно найти здесь .
Кроме того, я хотел бы рассмотреть возможность изменения вашего валидатора расписания комнат для свойства start на NotEqual
, так как похоже, что вы хотите вызвать эту ошибку проверки, когда start равно end; расширение Equal
вызовет сообщение проверки, только если они не равны. Это как утверждение, если они равны, все хорошо, в противном случае возвращает ошибку проверки. Документ для расширения Equal
:
/// <summary>
/// Defines an 'equals' validator on the current rule builder using a lambda to specify the comparison value.
/// Validation will fail if the value returned by the lambda is not equal to the value of the property.
/// </summary>
РЕДАКТИРОВАТЬ: Для проверки перекрытия я предположил, что время начала и окончания между расписаниями может быть одинаковым, например, конец 1 расписания == 13:00 && запуск расписания 2 2 == 13:00 не являются совпадением. Измените сравнение, чтобы использовать <= и> =, чтобы вообще не перекрывать.