NHibernate 不知道如何处理开箱即用的 TcpClient 等复杂类型。但它允许您提供自己的加载和存储代码。您可以使用IUserType:
public class TcpClientMapper : IUserType {
public SqlType[] SqlTypes {
get {
return new[] {
new SqlType(DbType.String),
new SqlType(DbType.Int32)
};
}
}
public Object NullSafeGet(IDataReader rs, String[] names, ...) {
String address = NHibernateUtil.String.NullSafeGet(rs, names[0]);
Int32 port = NHibernateUtil.Int32.NullSafeGet(rs, names[1]);
return new TcpClient(address, port);
}
public void NullSafeSet(IDbCommand cmd, Object value, Int32 index) {
TcpClient tcpClient = value as TcpClient;
if(tcpClient == null) {
NHibernateUtil.String.NullSafeSet(cmd, null, index);
NHibernateUtil.Int32.NullSafeSet(cmd, null, index + 1);
} else {
EndPoint red = tcpClient.Client.RemoteEndPoint;
IPEndPoint endpoint = ((IPEndPoint)red);
NHibernateUtil.String.Set(cmd, endpoint.Address.ToString(), index);
NHibernateUtil.Int32.Set(cmd, endpoint.Port, index + 1);
}
}
public Type ReturnedType {
get { return typeof(TcpClient); }
}
// TODO: implement other methods
}
并在 hbm 中像这样映射它:
<property name="_tcpClient" type="MyNamespace.TcpClientMapper, MyAssembly">
<column name="Address" /> <!-- NullSafeGet/Set index == 0 -->
<column name="Port" /> <!-- NullSafeGet/Set index == 1 -->
</property>
或使用流畅的UserTypeConvention:
public class TcpClientUserTypeConvention : UserTypeConvention<TcpClientMapper> {
}