2

我有这种情况:

我正在使用 Nhibernate 映射一个实体“ User ”,该实体“ User ”映射到 Sql 中的一个大表上,出于性能原因,我创建了一个轻量级实体“ LightweightUser ”,它只有一小部分属性并且没有映射到 hbm文件或其他任何东西,我正在使用Nhibernate 投影技术来连接“ LightweightUser ”实体。这两个实体都派生自一个包含 Id 属性的简单类“实体”。

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

但是在我的 Nhibernate SessionFactory 中,我还注入了一个Nhibernate Intercerptor。当我从 NHibernate Dao 获取“ User ”实体时,将调用 Interceptor的OnLoad方法,但是当我从 NHibernate Dao 获取“ LightweightUser ”实体时,不会触发Interceptor (OnLoad 方法)。

这可能与 NHibernate SessionFactory 不知道我的“LightweightUser”实体有关。有没有办法通知 Sessionfactory/Interceptor 我的“轻量级”实体的存在?还是有一些其他技术可以将投影连接到拦截器?是的,我也可以为我的轻量级实体复制“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);
    }

提前致谢

4

1 回答 1

2

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

如果您想为实体和 LightweightUser 元组应用相同的代码,您可以实现您的自定义 IResultTransformer 包含一个实例

Transformers.AliasToBean(typeof(LightweightUser))

并在调用原始转换器方法后应用您的逻辑

//do stuff

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

于 2013-07-01T09:40:36.043 回答