有时候在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映射即可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构