Я нашел возможное решение: 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();
}
}