有时候在NHibernate中的基本数据类型可能不够好用,可以考虑自定义一个数据类型。 可以通过实现IUserType或者ICompositeUserType接口来实现这一功能。 ICompositeUserType较IUserType而言可以提供更多的控制。一般情况我们实现IUserType即可。 IUserType Members
自定义数据类:
using
System;
using
System.Collections;
using
System.Data;
using
System.Text;
using
NHibernate;
using
NHibernate.SqlTypes;
namespace
Index.Data.NHibernateHelper
{ /**/ /// <summary> /// 自定义的NH数据类型,使用;分隔存储多个数据 /// </summary> public class DDLList : IUserType { private static readonly char SPLITTER = ' ; ' ; private static readonly SqlType[] TYPES = new SqlType[] {NHibernateUtil.String.SqlType} ; IUserType 成员 #region IUserType 成员 /**/ /// <summary> /// 提供自定义的完全复制方法 /// </summary> /// <param name="value"></param> /// <returns></returns> public object DeepCopy( object value) { if (value == null ) { return null ; } IList sourceList = (IList) value; IList targetList = new ArrayList(); for ( int i = 0 ; i < sourceList.Count; i ++ ) { targetList.Add(sourceList[i]); } return targetList; } /**/ /// <summary> /// 本类型实例是否可变 /// </summary> public bool IsMutable { get { return false ; } } /**/ /// <summary> /// 返回数据 /// </summary> /// <param name="rs"></param> /// <param name="names"></param> /// <param name="owner"></param> /// <returns></returns> public object NullSafeGet(IDataReader rs, string [] names, object owner) { string value = ( string ) NHibernateUtil.String.NullSafeGet(rs, names[ 0 ]); if (value != null ) { return StringToList(value); } else { return null ; } } /**/ /// <summary> /// 设置数据 /// </summary> /// <param name="cmd"></param> /// <param name="value"></param> /// <param name="index"></param> public void NullSafeSet(IDbCommand cmd, object value, int index) { if (value != null ) { string str = ListToString((IList) value); NHibernateUtil.String.NullSafeSet(cmd, str, index); } else { NHibernateUtil.String.NullSafeSet(cmd, value, index); } } /**/ /// <summary> /// 返回的Sql /// </summary> public Type ReturnedType { get { return typeof (IList); } } /**/ /// <summary> /// 返回的Sql类型 /// </summary> public SqlType[] SqlTypes { get { return TYPES; } } public new bool Equals( object x, object y) { if (x == y) { return true ; } if (x != null && y != null ) { IList xList = (IList)x; IList yList = (IList)y; if (xList.Count != yList.Count) { return false ; } for ( int i = 0 ; i < xList.Count; i ++ ) { string str1 = ( string )xList[i]; string str2 = ( string )yList[i]; if (str1 != str2) { return false ; } } return true ; } return false ; } #endregion /**/ /// <summary> /// 将string拼装成一个字符串,以“;”分隔 /// </summary> /// <param name="list"></param> /// <returns></returns> private string ListToString(IList list) { if (list.Count == 0 ) { return null ; } StringBuilder sb = new StringBuilder(); for ( int i = 0 ; i < list.Count - 1 ; i ++ ) { sb.Append(list[i]).Append(SPLITTER); } sb.Append(list[list.Count - 1 ]); return sb.ToString(); } /**/ /// <summary> /// 将“;”分隔的字符串解析为数组 /// </summary> /// <param name="value"></param> /// <returns></returns> private IList StringToList( string value) { string [] strs = value.Split(SPLITTER); IList emailList = new ArrayList(); for ( int i = 0 ; i < strs.Length; i ++ ) { emailList.Add(strs[i]); } return emailList; } } }
在映射文件中如此设置
<
property
name
="Email1"
type
="Index.Data.NHibernateHelper.DDLList,Index.Data.NHibernateHelper"
column
="Email1"
/>
在实体类中直接使用IList映射即可。