NHibernate:使用自定义类型作为主键
我有一个遗留模式,其中包含具有二进制(16)类型主键的表——它是其他列的MD5散列。NHibernate不使用byte[]作为键,因为它不实现Equals,所以我将其包装在自定义类型中,并为NHibernate提供了IUserType的实现。请注意,MD5Hash是一个结构而不是一个类NHibernate:使用自定义类型作为主键,nhibernate,hibernate,Nhibernate,Hibernate,我有一个遗留模式,其中包含具有二进制(16)类型主键的表——它是其他列的MD5散列。NHibernate不使用byte[]作为键,因为它不实现Equals,所以我将其包装在自定义类型中,并为NHibernate提供了IUserType的实现。请注意,MD5Hash是一个结构而不是一个类 public struct MD5Hash : IComparable, IComparable<MD5Hash>, IEquatable<MD5Hash> { private r
public struct MD5Hash : IComparable, IComparable<MD5Hash>, IEquatable<MD5Hash> {
private readonly byte[] contents;
...
}
问题似乎是NHibernate无法判断MD5Hash.Empty是否表示没有值。您是否尝试过创建自定义事件侦听器(如以下内容)来处理此问题?比如:
public class CustomLoadListener : DefaultLoadEventListener {
public override void OnLoad(LoadEvent @event, LoadType loadType) {
if(@event.EntityId is MD5Hash) {
var id = (MD5Hash) @event.EntityId;
if(id == MD5Hash.Empty) {
@event.Result = new Referenced { Id = MD5Hash.Empty };
return;
}
}
base.OnLoad(@event, loadType);
}
}
public class CustomSaveOrUpdateListener : DefaultSaveOrUpdateEventListener {
public override void OnSaveOrUpdate(SaveOrUpdateEvent @event) {
var entity = @event.Entity as Referenced;
if(entity != null && entity.Id == MD5Hash.Empty) {
return;
}
base.OnSaveOrUpdate(@event);
}
}
然后,您必须通过hibernate.cfg.xml在会话工厂中配置这些侦听器:
<session-factory>
<!-- various properties -->
<listener type="load" class="NhHacking.CustomLoadListener, NhHacking"/>
<listener type="save-update" class="NhHacking.CustomSaveOrUpdateListener, NhHacking"/>
</session-factory>
如果有人对如何实现这一点有更好的想法,我很乐意听到。MD5Hash IUserType的代码将非常有助于回答您的问题。此外,哈希作为PK是一个糟糕的想法。@james我添加了代码,但不相信它会有帮助。我仔细检查了NHibernate代码,发现它根据null而不是default测试了来自NullSafeGet的结果,也没有根据我为“未保存的值”提供的值进行测试。@diego grated。这就是为什么我提到它是一个遗留模式。
public class CustomLoadListener : DefaultLoadEventListener {
public override void OnLoad(LoadEvent @event, LoadType loadType) {
if(@event.EntityId is MD5Hash) {
var id = (MD5Hash) @event.EntityId;
if(id == MD5Hash.Empty) {
@event.Result = new Referenced { Id = MD5Hash.Empty };
return;
}
}
base.OnLoad(@event, loadType);
}
}
public class CustomSaveOrUpdateListener : DefaultSaveOrUpdateEventListener {
public override void OnSaveOrUpdate(SaveOrUpdateEvent @event) {
var entity = @event.Entity as Referenced;
if(entity != null && entity.Id == MD5Hash.Empty) {
return;
}
base.OnSaveOrUpdate(@event);
}
}
<session-factory>
<!-- various properties -->
<listener type="load" class="NhHacking.CustomLoadListener, NhHacking"/>
<listener type="save-update" class="NhHacking.CustomSaveOrUpdateListener, NhHacking"/>
</session-factory>