NHibernate Interceptor(s)在预测中的用法

时间:2013-01-16 16:19:08

标签: c# interceptor nhibernate-criteria nhibernate-projections

我遇到这种情况:

我正在使用Nhibernate来映射映射到Sql中的大型表的实体“用户”,出于性能原因我创建了一个轻量级实体' LightweightUser '只有一小部分属性并且 NOT 映射到hbm文件或其他什么,我使用 Nhibernate Projection 技术连接' LightweightUser '实体。两个实体都派生自一个包含Id属性的简单类“Entity”。

以上实现工作正常,sql查询更小==更快。

但在我的Nhibernate SessionFactory中,我还注入了一个 Nhibernate Intercerptor 。 当我从NHibernate Dao获得'用户'实体时,会调用拦截器的 OnLoad 方法,但当我得到' LightweightUser 来自NHibernate Dao的实体拦截器未触发(OnLoad方法)。

这可能与NHibernate SessionFactory不知道我的'LightweightUser'实体有关。有没有办法通知Sessionfactory / Interceptor我的'轻量级'实体的存在?或者是否有其他技术将预测线连接到拦截器?是的,我也可以为我的Lightweight实体复制'hbm'文件,但这似乎是不好的做法。

    [TestFixture]
    public class InterceptorTest : NhibernateSessionHelper
    {
    [Test]
    public void GetEntiy()
    {
        //ok trigger OnLoad in the Interceptor
        var user = GetSession().Get<User>(1);
        Assert.IsNotNull(user);
    }

    [Test]
    public void GetProjection()
    {
        var crit = GetSession().CreateCriteria<User>();
        crit.Add(Restrictions.Eq("Id", 5));
        crit.SetProjection(Projections.ProjectionList()
                                      .Add(Projections.Property("Id"), "Id")
                                      .Add(Projections.Property("Username"), "UserName"));

        crit.SetResultTransformer(Transformers.AliasToBean(typeof(LightweightUser)));

        //does not trigger the Interceptor
        var result = crit.List<LightweightUser>();

        Assert.IsNotNull(result.First());

    }
} 


    //Wire the Sessionfactory with Interceptor
    private static ISessionFactory CreateSessionFactory()
    {
        return new Configuration()
        .CurrentSessionContext<ThreadStaticSessionContext>()
        .SetInterceptor(new MyInterceptor())
            .Configure().BuildSessionFactory();
    }


 public class MyInterceptor: IInterceptor
{
    public override bool OnLoad(object entity, object id, object[] state, string[] propertyNames, NHibernate.Type.IType[] types)
    {
        //do stuff

        var s = entity;
        return base.OnLoad(entity, id, state, propertyNames, types);
    }

提前致谢

1 个答案:

答案 0 :(得分:2)

仅在处理PreLoadEvent时调用Interceptor的方法OnLoad。这有两种情况:从数据库加载实体时,或者从缓存中组装实体时。使用像您这样的投影创建的对象不被视为实体。

如果要为实体和LightweightUser的元组应用相同的代码,可以实现包含

实例的自定义IResultTransformer
Transformers.AliasToBean(typeof(LightweightUser))

并在调用原始变换器方法后应用

的逻辑
//do stuff

如果想了解更多关于拦截器的信息,我建议您从这里开始阅读我的博客条目列表:http://blog.scooletz.com/2011/02/03/nhibernate-interceptor-magic-tricks-pt-1/