2013-02-20 2 views
0

У меня следующая ситуация:NHibernate Фильтрация данных лучших практик

пользователь входит в систему, открывает обзор всех продуктов, могут видеть только список продуктов, где добавляется условие, это условие является переменной величиной. Пример: WHERE category in ('catA', 'CatB')

Администратор регистрируется, открывает обзор всех продуктов, он может видеть все продукты, не применяемые фильтром.

Мне нужно сделать это как можно более динамично. Мои классы доступа к данным в большинстве случаев используют Generics.

Я видел filters, но мои условия очень переменные, поэтому я не вижу в этом достаточно масштабируемого.

ответ

2

Мы используем фильтры NH для чего-то подобного, и он отлично работает. Если фильтр не требуется применять, вы можете опустить значение для фильтра. Мы используем эти фильтры для более простых элементов, фильтры, которые применяются почти в 100% случаев, фильтры удаленных объектов fx, разделение данных клиентов и т. Д. Не знаете, какой аспект масштабируемости вы ищете?

Для более высокого уровня и сложной фильтрации мы используем пользовательский класс, который управляет корнем репозитория. Что-то вроде следующий:

public IQueryOver<TIn, TOut> Apply(IQueryOver<TIn, TOut> query) 
{ 
     return query.Where(x => ...); 
} 

Если у вас есть IoC контейнер интегрирован с использованием NH, что-то, как это может быть легко обобщены и подключены к стеке. У нас есть эти манипуляторы репозитория, которые делают простые, где клаузулы, и другие, которые генерируют комплекс, где клаузулы, которые ссылаются на логику домена и другие, которые объединяют вторую таблицу и фильтруют ее.

+0

Да, я думаю, я могу сделать что-то подобное, хранить фильтры в какой-то сессии пользователя (веб-окружение). Большинство фильтров будут на самих столбцах таблицы, а не на объединениях. –

+0

Хорошо работает. Наша среда также является сайтом ASP.NET, мы используем пользовательскую фабрику «DefaultTypedFactoryComponentSelector» с Castle.Windsor, которая вместе с классом атрибутов фильтра позволяет нам использовать фильтры-источники из нашего контейнера, используя только имя строки (из статического класса, содержащего жесткий кодированный фильтр имена) и которые могут быть установлены путем простого вызова Apply, опционально устанавливая некоторые данные контекста с помощью метода 'void SetValue (T value)' в интерфейсе. – Svend

0

Вы можете сохранить все категории в списке категорий и передать этот список в запрос. Если список не пуст и содержит элементы, которые вы можете работать со следующим:

List<string> allowedCategoriesList = new List<string>(); 
allowedCategoriesList.Add(...); 
... 
.WhereRestrictionOn(x => x.category).IsIn(allowedCategoriesList) 

Это важно только, чтобы пропустить эту запись, если у вас нет каких-либо фильтров (так, вы хотите, чтобы просмотреть все записи без фильтрации), так как в противном случае вы не увидите ни одного результата.

Смежные вопросы