Позвольте мне предвосхитить этот вопрос и заявить, что использование Entity Framework для нас не вариант.
В нашей финансовой организации есть бизнес-объекты, которые будут использоваться в различных решениях. У некоторых есть пользовательский интерфейс, у других нет. Валидация и бизнес-правила должны содержаться внутри сущности.
Я создаю код для DAL и DTO, сгенерированных для меня, и эти DAL используют procs для работы CRUD на БД (может быть SQL может быть Oracle).
Поэтому, когда я создаю MVC, WCF, консольные приложения и т. Д., Вопрос мучает, может ли быть реализован лучший метод проверки.
Вот пара типичных свойств в объекте сущности:
[DefaultValue("")]
public string Branch {
get { return _branch; }
set {
if (value != null && value == _branch) return;
const string propertyName = "Branch";
ValidationInstance.Clear(propertyName);
ValidationInstance.ValidateRequired(propertyName, value);
ValidationInstance.ValidateNumeric(propertyName, value);
ValidationInstance.ValidateLength(propertyName, value, 2);
_branch = value;
if (EntityState != EntityStateType.New)
EntityState = EntityStateType.Changed;
}
}
[DefaultValue(0)]
public decimal HighDefermentMargin {
get { return _highDefermentMargin; }
set {
if (value == _highDefermentMargin) return;
const string propertyName = "HighDefermentMargin";
ValidationInstance.Clear(propertyName);
ValidationInstance.ValidateRange(propertyName, value);
_highDefermentMargin = value;
if (EntityState != EntityStateType.New)
EntityState = EntityStateType.Changed;
}
}
Как видите, существует смесь аннотаций данных и явных обращений к классу проверки для выполнения все более детальной проверки.
В приложении MVC мы тщательно дублируем валидацию в ViewModel, чтобы получить валидацию на стороне клиента и на стороне сервера. Вот версия ViewModel того же свойства сверху:
[Required]
[Range(0.0, 99.99)]
[Display(Name = "High Deferment Margin")]
public decimal HighDefermentMargin { get; set; }
Основное отличие здесь заключается в том, что проверка в объекте загружает ошибки в коллекцию ошибок в классе Validation, к которой можно обращаться в момент, когда объект собирается сохранить себя. Если (! IsValid), то генерировать пользовательское исключение, которое содержит массив ошибок. Контроллер проходит через них и добавляет их в ModelState.
Я начинаю работать над некоторыми классами, в которых буквально пара сотен полей. Даже если они разбиты по ОО, количество полей все еще очень велико. Это кредитные сертификаты и т. Д., Которые содержат много данных для одной записи. Необходимость выписать валидацию для такого количества свойств заставляет меня рвать. Я не могу просто написать утилиту для генерации сущностей и валидации, потому что именно бизнес-правила управляют валидацией, а не базой данных. Значение поля может быть обнуляемым в БД, но не может быть сохранено как нулевое на основании бизнес-правил, или поле может быть пустым, но только если отдельное поле имеет значение и т. Д.
Итак, может ли использование одних аннотаций данных в модели представления и сущности одинаковым образом достичь одинаковых результатов? Я могу написать собственные валидаторы для нестандартной валидации, а затем бизнес-правила для более сложных вещей. Будут ли ошибки валидации доводиться до более высокого уровня от сущности, чтобы пользовательский интерфейс мог информировать пользователя так же, как ModelState? Что другие делают в такой же ситуации?