NHibernate应该将id分配给实体还是由应用程序处理?

NHibernate应该将id分配给实体还是由应用程序处理?,nhibernate,Nhibernate,我正在编写一个应用程序,并开始测试我的域模型实体。如果我创建一个实体公司的实例,如var Company=新公司(“我的公司”);我应该得到一个有效的实体,这意味着公司现在应该有一个正确的Id 所以问题是,目前我在hbm文件中定义的DB中生成Id,如下所示: <id name="ObjectIdentity" column="CompanyId" type="System.Guid" unsaved-value="00000000-0000-0000-0000-000000000000"&

我正在编写一个应用程序,并开始测试我的域模型实体。如果我创建一个实体公司的实例,如var Company=新公司(“我的公司”);我应该得到一个有效的实体,这意味着公司现在应该有一个正确的Id

所以问题是,目前我在hbm文件中定义的DB中生成Id,如下所示:

<id name="ObjectIdentity" column="CompanyId" type="System.Guid" unsaved-value="00000000-0000-0000-0000-000000000000">
  <generator class="guid.comb"/>
</id>
<id name="ID" column="id">
<generator class="identity" />
</id>

这在编写单元测试时会导致问题,因为我没有Id为的en实体,因为它没有触及测试中的db,也就是说我有一个无效的实体


现在,我应该在应用程序中分配Id,而不是让nhibernate负责,还是这样做是错误的?

如果使用db生成的标识,则需要保存实体以获取Id, 如果你想创造自己的身份,那没关系。 做适合你的事,只要记住你在测试时选择了什么


我通常决定每个类哪个更适合我-DB生成的还是我自己的。

如果使用DB生成的标识,则需要保存实体以获取id, 如果你想创造自己的身份,那没关系。 做适合你的事,只要记住你在测试时选择了什么


我通常决定每个类哪个更适合我-DB生成的还是我自己的。

您需要调用Session。在生成guid之前在实体上保存。您可以调用Session.Save生成实体,而不实际将其保存到数据库中。非常好地解释了这一点

您需要调用Session.Save才能生成guid。您可以调用Session.Save生成实体,而不实际将其保存到数据库中。做了相当不错的解释

Nhibernate应该为您生成Id。必须保护实体的Id属性。最好的方法是使用Nhibernate为您生成Id。必须保护实体的Id属性。最好的方法是使用

在大多数情况下,您应该让NHibernate完成它的工作,即处理持久性。这一点很重要,因为它允许您轻松地更改内容(我们从identity更改为hilo mid项目)


我想问你为什么关心新创建的对象是否有id?从业务的角度来看,持久性ID是不相关的,不应该通过单元测试进行检查。如前所述,这是集成测试的领域。在整个应用程序的其余部分中如何使用对象持久性Id,您应该小心。请记住,这不应被视为对象业务id/密钥。

在大多数情况下,您应该让NHibernate完成其工作,即处理持久性。这一点很重要,因为它允许您轻松地更改内容(我们从identity更改为hilo mid项目)


我想问你为什么关心新创建的对象是否有id?从业务的角度来看,持久性ID是不相关的,不应该通过单元测试进行检查。如前所述,这是集成测试的领域。在整个应用程序的其余部分中如何使用对象持久性Id,您应该小心。请记住,不应将其视为对象业务id/密钥。

NHibernate和应用程序都不应处理标识符。将其留给数据库,因为这是数据的唯一具体存储,也是应用程序中唯一知道已分配哪些ID以及哪些ID可用的部分

在数据库表上创建标识主键列:

CREATE TABLE dbo.sample (
id int primary key identity(1,1),
...
...
...)
像这样映射实体:

<id name="ObjectIdentity" column="CompanyId" type="System.Guid" unsaved-value="00000000-0000-0000-0000-000000000000">
  <generator class="guid.comb"/>
</id>
<id name="ID" column="id">
<generator class="identity" />
</id>


第一次保存新实体时,数据库将自动生成主键。IDENTITY(1,1)表示“给新行一个从“1”开始的标识,然后每个后续行递增1”:因此1,2,3,4,5,6,7无论是NHibernate还是应用程序都不应该处理标识符。将其留给数据库,因为这是数据的唯一具体存储,也是应用程序中唯一知道已分配哪些ID以及哪些ID可用的部分

在数据库表上创建标识主键列:

CREATE TABLE dbo.sample (
id int primary key identity(1,1),
...
...
...)
像这样映射实体:

<id name="ObjectIdentity" column="CompanyId" type="System.Guid" unsaved-value="00000000-0000-0000-0000-000000000000">
  <generator class="guid.comb"/>
</id>
<id name="ID" column="id">
<generator class="identity" />
</id>


第一次保存新实体时,数据库将自动生成主键。标识(1,1)意味着“给新行一个从“1”开始的标识,然后每个后续行递增1”:因此,1,2,3,4,5,6,7

在进行unittest时,关键是不要有“无效”实体,也就是没有DB。但是我刚刚读到一些关于为什么不应该使用指定方法的不好的东西。所以我提出了这个解决方案:只要通过一个聚合创建实体,在我所有的聚合都被注入一个存储库之后,我可以在我的测试中模拟/存根,这样我就可以确保创建的所有实体都有一个有效的Id。要点是在进行unittest时不要有“无效”实体,也就是没有DB。但是我刚刚读到一些关于为什么不应该使用指定方法的不好的东西。所以我提出了这个解决方案:只要通过一个聚合创建实体,在我所有的聚合都被注入一个存储库之后,我可以在测试中模拟/存根,这样我就可以确保创建的所有实体都有一个有效的Id。你可以用DB进行单元测试,并在单元测试结束时回滚事务。唯一的问题是,当您对NH进行单元测试时,标识会上升(尽管db中不会留下任何条目),这主要是为了针对db进行映射测试。(另外——无论谁否决——请解释)我刚刚在我的博客上发布了可能的解决方案,我想指出的是,在我看来,生成id的责任属于存储库。NHibernate只是存储库的一个技术实现细节。如果您有一个内存存储库,nhibernate将不会处理这个问题