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> {
}
我明白了。我将不得不实施IUserType的所有方法,然后我会假设它为了工作?如果是的话,你将如何实现这个NullSafeSet?我的类中的属性本身仍然是常规的TcpClient权利,还是需要将其更改为ClientMapper类? –
是的,你必须实现所有的方法,这并不难,看看答案中的链接。属性仍然是一个普通的TcpClient(从设计的角度来看这有点奇怪)。请参阅上次编辑NullSafeSet实现。 – Dmitry
这看起来不错,感谢您的帮助。 另一个快速问题?您如何知道发送到字符串[]数组的内容的顺序?我意识到你阅读的属性,但你怎么知道地址在位置0和阵列中的位置1的端口? 我问的原因是B/C我试图实现串行连接相同。 –