【问题标题】:NHibernate: Creating a criteria which applies for all queries on a tableNHibernate:创建适用于表上所有查询的条件
【发布时间】:2009-08-31 18:27:19
【问题描述】:

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

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

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

【问题讨论】:

    标签: nhibernate criteria castle-activerecord


    【解决方案1】:

    我终于找到了一个很好的解决方案(使用过滤器)。由于 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() 等永远不会触及超过一年的条目。

    【讨论】:

      【解决方案2】:

      【讨论】:

      • 这似乎是一个很好的解决方案,但是我不知道是否可以将这些过滤器与 Castle ActiveRecord 一起使用。
      • groups.google.com/group/castle-project-devel/browse_thread/… 我认为这从未实现过...您将获得当前的 ISession 并自己启用过滤器
      • IIRC 你可以从 ActiveRecordMediator.GetSessionFactoryHolder().CreateSession(typeof(ActiveRecordBase)) 获取当前的 ISession
      • 启用过滤器似乎是可能的,但如何创建过滤器是一个更大的问题。
      猜你喜欢
      • 1970-01-01
      • 2013-06-16
      • 2010-10-31
      • 1970-01-01
      • 2011-03-18
      • 2020-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多