NHibernate在从db加载和插入缓存之间修改实体

时间:2011-06-20 19:55:32

标签: nhibernate

在从数据库中检索实体并将其插入二级缓存之前,是否存在Interceptor,EventListener或NHibernate中的任何内容?

我有一个带有属性的类,可能包含类似

的内容
Lorem ipsum <c:link type="tag" id="123" /> dolor sit amet

我需要运行将其转换为

的插件
Lorem ipsum <a class="tag-link" href="/tags/tag-name/" title="Description of the tag">Tag name</a> dolor sit amet

如果启用了缓存,我只希望这样做一次:在将该实体插入缓存之前。

2 个答案:

答案 0 :(得分:0)

是的,NHibernate公开了拦截器和事件监听器契约。您可以选择使用拦截器或事件来实现解决方案。我会推荐事件监听器。 NHibernate在NHibernate.Event命名空间中公开了许多事件监听器契约。请探索以下事件监听器合同: -

  • NHibernate.Event.IPostLoadEventListener
  • NHibernate.Event.ILoadEventListener

答案 1 :(得分:0)

我找到了一个可能的解决方案:UserTypes。

实体

public class Post : Page
{
    [FormattedText]
    public virtual string Text { get; set; }
}

映射

public class PostMapping : SubclassMap<Post>
{
    public PostMapping()
    {
        Map(x => x.Text);
    }
}

UserType(部分内容)

public class FormattedText: IUserType
{
    public object NullSafeGet(System.Data.IDataReader rs, string[] names, object owner)
    {
        string original = (string)NHibernateUtil.String.NullSafeGet(rs, names[0]);
        // this is where we do the text processing
        // TODO: the real implementation
        return new string(original.Reverse().ToArray());
    }
    // ...
}

Fluent NHibernate Convention用于映射自定义类型

public class FormattedTextConvention : IPropertyConvention
{
    public void Apply(IPropertyInstance instance)
    {
        if (instance.Property.PropertyType == typeof(string))
        {
            if (instance.Property.MemberInfo.GetCustomAttributes(typeof(FormattedTextAttribute), true).Any())
            {
                instance.CustomType<FormattedText>();
            }
        }
    }
}

创建SessionFactory

public class NHibernateThingy
{
    public static ISessionFactory CreateSessionFactory(bool isAdminMapping)
    {
        var config = Fluently.Configure();
        config.Database(/* ... */);
        if (isAdminMapping)
        {
            // don't format strings when editing entities
            // so no FormatTextConvetion here
            config.Mappings(m => m.FluentMappings.AddFromAssemblyOf<Content>());
        }
        else
        {
            // format string when displaying
            config.Mappings(m => m.FluentMappings.AddFromAssemblyOf<Content>().Conventions.Add(typeof(FormattedTextConvention)));
            // use cache to run that heavy text processing only once
            config.Cache(c => c.ProviderClass<SysCacheProvider>().UseSecondLevelCache());
        }

        return config.BuildSessionFactory();
    }
}