流畅的NHibernate:“......当在内存中创建一个新对象时,它的身份字段是未定义的”

时间:2011-08-14 18:55:45

标签: nhibernate fluent-nhibernate fluent

有没有人知道如何制作对象,以便 在其标识字段中有一些东西 - 这样我就可以使用它来获取哈希码。

2 个答案:

答案 0 :(得分:2)

一种选择是使用Guid作为id。这样您就不需要数据库往返来获取身份值。

    <id name="_id" column="PersonId" >
        <generator class="assigned" />
    </id>

Id(x => x.Id)
  .Column("PersonId")
  .GeneratedBy.Assigned();
如果您使用SQL Server,

'PersonId'列类型应为uniqueidentifier。然后,当您创建对象时,可以使用Guid.NewGuid()生成新ID。

public class Person {
    private Guid _id;

    public Person() {
        _id = Guid.NewGuid();
    }

    public Guid Id {
        get { return _id; }
    }
}

这种方法的优点是您的代码与数据库的分离更多。这在测试期间非常有用,如果您需要支持“断开连接”的方案。潜在的缺点是连接期间的性能(google“guid vs int primary key”)。有关NHibernate中id生成器的更多信息,请参阅this

作为旁注,您可能希望rethink设计并使用商家密钥实施Equals and GetHashCode。在这种情况下,您不需要Guid身份。来自Don't Let Hibernate Steal Your Identity

  

“我们建议使用Business key实现equals()和hashCode()   平等。业务键平等意味着equals()方法   仅比较形成业务键的属性,即键   将识别我们在现实世界中的实例(一个自然的候选人   key)“(Hibernate Reference Documentation v.3.1.1)。

答案 1 :(得分:1)

这取决于你想要实现你的工作单元的多长时间的并发性......虽然GUId id和HILO id听起来都很花哨而且大部分时间都很酷,但它们并不是必需的。

关于你的问题,如果id是由db生成的自动递增的id,你需要在数据库上保存要生成的id,这可能会暂时锁定该表,直到你的事务被提交但是具有自动递增id

的缺点之一

另一件事为什么你会保存和比较对象与其他东西绑定的不同ID ...

说学生是你的班级,有两个属性Id,Name,School

现在,如果你想看看它是否是同一个学生那么你可能想要在Name和School而不是Id上生成哈希