NHibernate изменить сущность между загрузкой из БД и вставкой в ​​кеш - PullRequest
0 голосов
/ 20 июня 2011

Есть ли в NHibernate Interceptor, EventListener или что-либо еще, что выполняется после извлечения сущности из базы данных и перед ее вставкой в ​​кэш 2-го уровня?

У меня есть класс со свойством, которое может содержать что-то вроде

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 голосов
/ 21 июня 2011

Я нашел возможное решение: UserTypes.

Entity

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

Mapping

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());
    }
    // ...
}

Свободное соглашение NHibernate для отображения пользовательского типа

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();
    }
}
0 голосов
/ 21 июня 2011

Да, NHibernate предоставляет контракты на перехватчик и прослушиватель событий. У вас есть возможность реализовать решение с использованием перехватчика или событий.Я бы порекомендовал слушателей событий.NHibernate предоставляет множество контрактов прослушивателей событий в пространстве имен NHibernate.Event.Пожалуйста, изучите следующие контракты прослушивателя событий: -

  • NHibernate.Event.IPostLoadEventListener
  • NHibernate.Event.ILoadEventListener
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...