MVC - Доменная служба берет на себя ответственность за фильтрацию или уровень хранилища? - PullRequest
5 голосов
/ 18 января 2011

Должен ли я фильтровать результаты IQueryable от службы домена?

Например ... Мои 3 портала (веб-сайты) имеют доступ к одному и тому же уровню обслуживания домена, в зависимости от типа пользователя, я вызываю определенный метод репозитория и возвращаю результат

Текущий слой репозитория:

    IQueryable<Products> GetAllProductsForCrazyUserNow(CrazyUser id);
    Products GetAProductForCrazyUserNow(CrazyUser id,product id);

    IQueryable<Products> GetProductsForNiceUserNow(NiceUser id);
    Products GetProductsForNiceUserNow(NiceUser id,product id);

Лучше всего сделать это на уровне хранилища:

    IQueryable<Products> GetAllProducts();
    Products GetAProduct(product id);

Затем в доменной службе я просто делаю фильтр, т. Е.

var Niceman = IQueryable<Products> GetAllProducts().Where(u=> u.Name == "Nice");

ПРИМЕЧАНИЕ. У меня есть сеанс только для чтения и сеанс, который включает CRUD на уровне хранилища, поэтому имейте это в виду при ответе.

Второй вопрос. Должен ли я вообще выполнять какую-либо фильтрацию на уровне службы домена? Этот слой является единственным слоем, который может изменить сущность, т.е. Product.Price == 25,00; Это не делегируется уровню хранилища.

Ответы [ 3 ]

2 голосов
/ 18 января 2011

Харун,

Я использую методы расширения на IQueryable<Classes> ВНЕ РЕПО. на самом деле, у меня есть набор классов, которые я называю «фильтрами», и они, как правило, примерно такие:

public static class ProductFilters
{
    public static IQueryable<Products> NiceMan(
        this IQueryable<Products> customQuery, string filterName)
    {
        if (!string.IsNullOrEmpty(filterName))
           customQuery = customQuery.Where(u => u.Name == filterName);
        return customQuery;
    }
   // create lots of other Products based filters here
   // and repeat with seperate IQueryable<Classes> per type
}

использование:

var Niceman = IQueryable<Products> GetAllProducts().NiceMan("Nice");

Я считаю это хорошим разделением логики и поддерживает чистоту репо. И в ответ на второй вопрос, да, используйте эту логику фильтра / расширения внутри сервисного уровня, а не репо.

1 голос
/ 18 января 2011

Обычно я использую уровень репозитория для выполнения простой работы CRUD, а уровень домена выполняет любую бизнес-логику или, в вашем случае, любую фильтрацию, которая необходима перед передачей этих данных обратно на уровень пользовательского интерфейса.

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

0 голосов
/ 04 мая 2011

У меня сам был такой же вопрос.Мое сомнение было поместить его на сервисный уровень, так как в некоторых случаях процесс фильтрации мог удалить большую часть записей, возвращаемых из репозитория, и я не хотел извлекать из базы данных больше данных, чем необходимо.

* 1002В итоге я перешел на NHibernate, и мои методы хранилища приняли DetachedCriteria аргументы.Затем я передал пользовательскую информацию на сервисный уровень, и она выполняла фильтрацию не путем манипулирования IQueryable, а путем создания объекта DetachedCriteria и передачи его в репозиторий, таким образом модифицируя SQL и ограничивая работу базы данных.

Пока что, похоже, он работает довольно хорошо и "чувствует себя хорошо", так как моя логика довольно солидна на уровне обслуживания, а репо выполняет только базовую CRUD.

...