是否可以基于NHibernate多列用户类型(最好通过QueryOver)对查询进行排序?
我有一个fluent映射的数据库表,它使用两列表示IP地址。一列是字符串鉴别器,是否可以基于NHibernate多列用户类型(最好通过QueryOver)对查询进行排序?,nhibernate,queryover,Nhibernate,Queryover,我有一个fluent映射的数据库表,它使用两列表示IP地址。一列是字符串鉴别器,address\u family表示地址系列(IPv4与IPv6),第二列是addressavarbinary(16),它以网络字节顺序表示IP地址(开头是最有效字节的大端字节) 映射通过自定义的IUserType配置,如下所示 Map(x=>x.Address) .CustomType() .Columns.Clear() .列。添加(“地址\家庭”、“地址”) .Not.Nullable(); 自定义IpAdd
address\u family
表示地址系列(IPv4与IPv6),第二列是address
avarbinary(16)
,它以网络字节顺序表示IP地址(开头是最有效字节的大端字节)
映射通过自定义的IUserType配置,如下所示
Map(x=>x.Address)
.CustomType()
.Columns.Clear()
.列。添加(“地址\家庭”、“地址”)
.Not.Nullable();
自定义IpAddressBinaryUserType
(实现如下所示)按预期实现IUserType
,将列映射到所需的IPAddress
。但是,似乎没有任何明显的功能来应用OrderBy
子句,例如,在本例中,该子句允许我按address\u系列
列降序,然后按address
列升序。当然,我可以在查询运行后手动执行此操作,但显然这大大限制了我从大型数据集中分页数据的能力
使用系统;
使用System.Collections.Generic;
使用System.Data.Common;
使用System.Linq;
Net系统;
使用System.Net.Sockets;
使用NHibernate;
使用NHibernate.发动机;
使用NHibernate.SqlTypes;
使用NHibernate.UserTypes;
命名空间NHibernate.UserTypes
{
///
///用于将IP地址持久化为数据库中的2列的用户类型(字符串AddressFamily,二进制地址)
///
///映射(x=x.Address)
///.CustomType&;lt;IPAddressBinaryUserType&;gt;()
///.Columns.Clear()
///.列。添加(“地址\家庭”、“地址”)
///.Not.Nullable();
///
///
公共类IpAddressBinaryUserType:IUserType
{
私有常量int AddressFamilyColumn=0;
私有常量int字节列=1;
///
///用于自定义映射的Sql类型
///
公共SqlType[]SqlTypes=>new[]
{
NHibernateUtil.String.SqlType,//地址族
NHibernateUtil.Binary.SqlType//地址
};
///
public bool IsMutable=>false;
///
公共类型ReturnedType=>typeof(IPAddress);
#来自接口IUserType的区域
///
公共对象集合(对象缓存,
对象所有者)
{
返回此.DeepCopy(缓存);
}
///
public void NullSafeSet(DbCommand cmd,
对象值,
整数索引,
iSession(实施者会话)
{
if(值为IPAddress地址)
{
NHibernateUtil.String.NullSafeSet(cmd,address.AddressFamily.ToString(),index,session);
NHibernateUtil.Binary.NullSafeSet(cmd,address.GetAddressBytes(),索引+1,会话);
}
其他的
{
NHibernateUtil.String.NullSafeSet(cmd、null、index、session);
NHibernateUtil.Binary.NullSafeSet(cmd,null,index+1,session);
}
}
///
公共对象深度复制(对象值)
{
返回值;
}
///
公共对象(对象值)
{
返回此.DeepCopy(值);
}
///
公共新布尔等于(对象x,
对象(y)
{
if(ReferenceEquals(x,y))
{
返回true;
}
如果(x==null
||y==null)
{
返回false;
}
返回x等于(y);
}
///
公共int GetHashCode(对象x)
{
返回x.GetHashCode();
}
///
///基于解析或列映射无法执行get
公共对象NullSafeGet(DbDataReader rs,
字符串[]名称,
ISessionImplementor会话,
对象所有者)
{
var addressFamilyString=NHibernateUtil.String.NullSafeGet(rs,名称[AddressFamilyColumn],会话)作为字符串;
var bytes=NHibernateUtil.Binary.NullSafeGet(rs,名称[BytesColumn],会话)作为字节[];
//没有价值
if(string.IsNullOrWhiteSpace(addressFamilyString)
&&字节==空)
{
返回null;
}
//获取家庭地址
如果(!Enum.TryParse((addressFamilyString??string.Empty).Trim(),
是的,
输出地址(家庭地址(家庭))
{
抛出新的HibernateException($“地址族\“{addressFamilyString}\”通过映射命名为列\“{names[AddressFamilySColumn]}\”未被识别”);
}
如果(字节==null)
{
抛出新的HibernateException($”通过映射命名为列\“{names[BytesColumn]}\”的字节不可识别);
}
var地址=新的IPAddress(GetBytes(addressFamily,bytes));
如果(address.AddressFamily!=AddressFamily)
{
抛出新的HibernateException($“期望IP地址属于地址族{addressFamily}”);
}
回信地址;
}
///
公共对象替换(对象原始,
目标,,
对象所有者)