Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
NHibernate:使用自定义类型作为主键_Nhibernate_Hibernate - Fatal编程技术网

NHibernate:使用自定义类型作为主键

NHibernate:使用自定义类型作为主键,nhibernate,hibernate,Nhibernate,Hibernate,我有一个遗留模式,其中包含具有二进制(16)类型主键的表——它是其他列的MD5散列。NHibernate不使用byte[]作为键,因为它不实现Equals,所以我将其包装在自定义类型中,并为NHibernate提供了IUserType的实现。请注意,MD5Hash是一个结构而不是一个类 public struct MD5Hash : IComparable, IComparable<MD5Hash>, IEquatable<MD5Hash> { private r

我有一个遗留模式,其中包含具有二进制(16)类型主键的表——它是其他列的MD5散列。NHibernate不使用byte[]作为键,因为它不实现Equals,所以我将其包装在自定义类型中,并为NHibernate提供了IUserType的实现。请注意,MD5Hash是一个结构而不是一个类

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>