NHibernate: создание критерия, который применяется ко всем запросам в таблице.

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

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

Есть ли способ принудительно включить предложение WHERE во все запросы к Castle ActiveRecord?


person mbp    schedule 31.08.2009    source источник


Ответы (2)


Наконец-то я нашел отличное решение (с использованием фильтров). Поскольку 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 () и т. Д. Никогда не будут касаться записей старше года.

person mbp    schedule 03.09.2009

Наиболее близким было бы использование фильтров. См. http://ayende.com/Blog/archive/2009/05/04/nhibernate-filters.aspx

person Mauricio Scheffer    schedule 31.08.2009
comment
Это кажется хорошим решением, однако я не могу понять, можно ли использовать эти фильтры с Castle ActiveRecord. - person mbp; 02.09.2009
comment
groups.google.com/group/castle-project- devel / browse_thread / Я не думаю, что это когда-либо было реализовано ... вы получите текущий ISession и сами включите фильтры - person Mauricio Scheffer; 02.09.2009
comment
IIRC, вы можете получить текущий ISession из ActiveRecordMediator.GetSessionFactoryHolder (). CreateSession (typeof (ActiveRecordBase)) - person Mauricio Scheffer; 02.09.2009
comment
Включение фильтра кажется возможным, но как его создать - большая проблема. - person mbp; 03.09.2009