2009-08-31 7 views
2

Использование Castle ActiveRecord/NHibernate: есть ли способ заставить ICriterion выполнять все запросы на таблице?NHibernate: создание критерия, который применяется для всех запросов в таблице

Например, у большого количества моих таблиц есть столбец «UserId». Возможно, я хочу, чтобы я всегда выбирал строки для зарегистрированного пользователя. Я могу легко создать объект ICriterion, но я вынужден предоставить его для разных методов: FindAll(), FindFirst(), FindLast() и т. Д.

Есть ли способ принудительно сделать предложение WHERE по всем запросам Замок ActiveRecord?

ответ

3

Я, наконец, нашел отличное решение (используя фильтры). Поскольку у Castle AR нет какого-либо встроенного API для сопоставления фильтрам NHibernate, эта часть была почти недокументирована. Так вот.

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

Сначала создайте ActiveRecord «Новости».

Используйте этот код перед инициализацией ActiveRecordStarter.

ActiveRecordStarter.MappingRegisteredInConfiguration += MappingRegisteredInConfiguration; 
Castle.ActiveRecord.Framework.InterceptorFactory.Create =() => { return new EnableFiltersInterceptor(); }; 

Затем добавьте недостающую функцию и класс:

void MappingRegisteredInConfiguration(Castle.ActiveRecord.Framework.ISessionFactoryHolder holder) 
{ 
    var cfg = holder.GetConfiguration(typeof (ActiveRecordBase)); 

    var typeParameters = new Dictionary<string, IType> 
            { 
            {"AsOfDate", NHibernateUtil.DateTime} 
            }; 

    cfg.AddFilterDefinition(new FilterDefinition("Latest", "", typeParameters)); 

    var mappings = cfg.CreateMappings(Dialect.GetDialect(cfg.Properties)); 

    var newsMapping = cfg.GetClassMapping(typeof (News)); 
    newsMapping.AddFilter("Latest", ":AsOfDate <= Date"); 
} 


public class EnableFiltersInterceptor : EmptyInterceptor 
{ 
    public override void SetSession(ISession session) 
    { 
     session.EnableFilter("Latest").SetParameter("AsOfDate", DateTime.Now.AddYears(-1)); 
    } 
} 

И вуаля! Запросы в новостях, например. FindAll(), DeleteAll(), FindOne(), Exists() и т. Д. Никогда не будут касаться записей больше года.

1

Ближайшая вещь будет использовать фильтры. См. http://ayende.com/Blog/archive/2009/05/04/nhibernate-filters.aspx

+0

Это, кажется, хорошее решение, однако я не могу понять, можно ли использовать эти фильтры с помощью Castle ActiveRecord. – mbp

+0

http://groups.google.com/group/castle-project-devel/browse_thread/thread/ce94f492615e0d52/c721a7abb0a1f1a7 Я не думаю, что это когда-либо было реализовано ... вы получите текущую ISession и включите фильтры самостоятельно –

+0

IIRC вы можете получить текущее ISession с ActiveRecordMediator.GetSessionFactoryHolder(). CreateSession (typeof (ActiveRecordBase)) –