如果你在数据库中有一个char(5)列并且你有"ABC"在那里,如果你将这个列映射到一个字符串属性你会发现nhibernate将它映射为"ABC__"其中下划线表示某种空白(我没有检查它是什么ascii码)
很长一段时间以来,我们只是通过将列改为varchar并修剪DB中的所有条目来解决这个问题。如果有一种解决方案可以让我们将列保持为char(n)(即使只是为了节省一些工作)
,那就更好了。我想我可以尝试在get上修剪,在set上填充,但这并不是最好的解决方案。
那么,是否有一些很好的方法来配置nhibernate读取字符(n)列到字符串中,而不需要额外的空白?
谢谢!
是,不是。您可以在字段标记上使用公式属性将值设置为RTrim(myCharField),但这样它就不会被绑定。也就是说,您对该字段所做的任何更改都不会保存到数据库中。
我真的不明白为什么这是一个问题。如果你正在设计你的应用程序与一个数据层,它应该是足够简单的添加一个trim调用的getter方法的实体的属性返回之前,不是吗?
我不确定您使用的是哪个数据库,但是我们使用iSeries DB2,并且我们在尾随空格时遇到了相同的问题。我们创建了一个自定义用户类型来"修剪"这些列中的值:
这是有效的,因为iSeries DB2在进行字符串比较时不考虑尾随空格(即'MYSTRING'等于'MYSTRING')。如果这对于您的特定数据库不是真的,您可能可以在"NullSafeSet"方法中处理它,通过使用数据库使用的空白字符进行右填充。
这是安迪要点的更新版本:
public class TrimmedString : NHibernateFactoryType<string>
{
public override SqlType[] SqlTypes => new[] { new SqlType(DbType.AnsiStringFixedLength) };
public override object NullSafeGet(DbDataReader rs, string[] names, ISessionImplementor session, object owner)
{
var str = (string)NHibernateUtil.String.NullSafeGet(rs, names[0], session);
return str?.Trim();
}
public override void NullSafeSet(DbCommand cmd, object value, int index, ISessionImplementor session)
{
value = ((string)value)?.Trim(); //Not really necessary
NHibernateUtil.String.NullSafeSet(cmd, value, index, session);
}
}