Как проверить бизнес-правила в сервисе или репо - PullRequest
1 голос
/ 13 июля 2011

Я надеюсь создать базовый класс сущностей, который включает в себя правило проверки, которое проверяет, является ли поле с именем «Заголовок» уникальным (что, конечно, требует сканирования БД). Я хочу, чтобы унаследованные модели запускали правило проверки на уровне репо (или службы) и отправляли ValidationResult на уровень клиента (MVC).

Проблема заключается в наследовании.

</p> <pre><code>public interface IUniqueTitle { int Id { get; set; } string Title { get; set; } // This is a "multi-client, one database" solution. // Data is isolated using SiteId int SiteId { get; set; } } // Models such as "MemberClub" and "Assessment" will inherit from this public class EntityUniqueTitle : IUniqueTitle { public int Id { get; set; } public int SiteId { get; set; } public string Title { get; set; } } // This class will be used in production public class MemberClub : EntityUniqueTitle { }

Я написал метод расширения, который проверяет, является ли поле «Название» уникальным на основе идентификатора сайта.

</p> <pre><code>public static bool IsUniqueTitle<T>(this IQueryable<T> items, T currentEntity) where T : IUniqueTitle { return items.Where( item => item.Id != currentEntity.Id // INCASE UPDATING OBJECT & item.SiteId == currentEntity.SiteId & item.Title == currentEntity.Title) .Count() == 0; }

Здесь я застреваю. Где я должен поставить валидацию?

Я могу положить в репо, но не могу понять, как запустить ValidationResult при сохранении

</p> <pre><code>public class RepoUniqueTitle<T> : IRepoUniqueTitle<T> where T : EntityUniqueTitle, new() { protected readonly DbContext c; public Repo(IDbContextFactory f) { c = f.GetContext(); } public void Insert(T o) { if (!c.Set<T>().IsUniqueTitle(o)) { // *********************** // PROBLEM HERE, HOW DO I STOP AND SEND A VALIDATIONRESULT TO THE CLIENT? // IF POSSIBLE, AUOTMATIC WHEN MODEL.ISVALID IS CALLED // code from base repo class for reference // if (o is IUniqueTitleForSite) // IoC.Resolve<IRepoUniqueTitle<T>>().Validate(o); } else c.Set<T>().Add(o); } }

Я надеюсь, что есть решение для проверки, которое:

  • Модели могут наследоваться от базовой сущности
  • Может делать вызовы БД в коллекцию унаследованной сущности
  • Работает с ValidationResult, поэтому его можно без проблем интегрировать в MVC Tier
  • Вызывается во время Model.isValid, если возможно

Примечание. Я использую ProDinner в качестве основы для решения n-уровневого кодирования в первую очередь EF mvc / wf.

Извините, многое для меня ново. Будем весьма благодарны за любую помощь, которую вы можете оказать!

1 Ответ

1 голос
/ 14 июля 2011

Если у вас есть отдельный слой бизнес-логики, вы должны поместить валидацию на этот слой. Иначе зачем иметь этот слой, если вы не используете его для выполнения бизнес-правил?

В любом случае уникальная проверка является сложной задачей, поскольку между вашим запросом и фактическим сохранением данных существует задержка, и другой поток может вставить элемент с таким же заголовком в течение этой задержки. Вы должны поместить уникальный индекс в Title и SiteId, чтобы обеспечить уникальность в базе данных. В таком случае прежняя проблема приведет к исключению, которое вы должны как-то обработать, но оно, вероятно, лучше, чем двуличность данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...