2

使用 Castle ActiveRecord / NHibernate:有没有一种方法可以对表上的所有查询强制使用 ICriterion?

例如,我的很多表都有一个“UserId”列。我可能想确保始终为登录用户选择行。我可以轻松地创建一个 Icriterion 对象,但我不得不为不同的方法提供它:FindAll()、FindFirst()、FindLast() 等。

有没有办法强制对 Castle ActiveRecord 的所有查询使用 WHERE 子句?

4

2 回答 2

3

我终于找到了一个很好的解决方案(使用过滤器)。由于 Castle AR 没有任何用于映射到 NHibernate 过滤器的原生 API,因此这部分几乎没有文档记录。所以这里。

这个示例过滤器将确保您永远不会收到超过一年的新闻,无论您在 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() 等,永远不会触及超过一年的条目。

于 2009-09-03T21:07:02.850 回答
1

最接近的事情是使用过滤器。请参阅http://ayende.com/Blog/archive/2009/05/04/nhibernate-filters.aspx

于 2009-08-31T19:11:35.847 回答