2009-11-03 73 views
2

我正在编写一个应用程序,并开始测试我的领域模型实体。如果我创建一个像这样var company = new Company(“my company”)的实体公司实例;我应该得到一个有效的实体,这意味着公司此时应该有一个Id是否正确?NHibernate应该为实体分配id还是应该由应用程序处理?

所以问题是,在那一刻我有一个HBM文件中像这样定义的ID生成的DB提出:编写单元测试的时候,因为我没有带实体做

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

这会导致一个问题有一个Id,因为它在测试中没有碰到db,又叫我有一个无效的实体。

现在我应该在应用程序中分配Id,而不是让nhibernate负责这个或者这是错误的做法吗?

+0

实体如何无效有一个ID?你想要测试什么? – 2009-11-04 01:50:58

回答

2

在大多数情况下,您应该让NHibernate完成它的工作,即处理持久性。这很重要,因为它可以让你轻松地改变事物(我们从身份到hilo中期项目)。

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

+0

你认为一个视图(比如一个网页视图)应该使用持久性ID来区分对象吗?如果不是,那么当没有真正独特的商业密钥时,他们应该如何区分对象?当session.save没有被调用时,这成为一个问题。 – Mank 2009-11-06 05:08:14

+0

我从来没有见过一个设计,当一个项目被添加时,它不会立即持续,然后加载一个新的数据集。原因是任何时候你添加一个实体后端都有业务规则(可能还有数据库约束)需要应用。 – 2009-11-10 20:40:18

-1

如果你想创建你自己的身份,你需要保存实体以获得一个ID,如果你使用db生成的身份,则 - 这很好。 做什么适合你,只要记住你在测试时选择了什么。

我通常会决定每一个更适合我的课程 - 无论是数据库还是我自己的课程。

+0

您可以使用数据库进行单元测试,并在单元测试结束时回滚事务。唯一的问题是身份会爬起来(尽管db中没有条目) 当你单元测试NH的时候,它主要是针对数据库映射测试。 (加上 - 谁downvote - 请解释) – Dani 2009-11-03 23:53:05

+0

我刚刚发布在我的博客可能的解决方案 http://techinject.blogspot.com/2009/11/how-to-unittest-entities.html – 2009-11-04 00:14:49

+0

我想要点在我看来,生成身份证的责任属于存储库。 NHibernate只是一个存储库的技术实现细节。如果你有一个内存存储库,nhibernate不会处理id :),但你仍然需要它们。 我关于无效实体的声明来自DDD实体的概念,定义实体的是它有一个身份,所以有人必须生成这个,现在我认为这个职责属于仓库 – 2009-11-04 19:46:32

0

在生成guid之前,您需要在实体上调用Session.Save。您可以调用Session.Save生成实体,而不实际将其保存到数据库中。 This article做了一个相当不错的工作解释它

+0

那么重点是在进行单元测试时没有“无效”实体,也就是没有数据库。但我只是读了一些关于为什么你不应该使用指定方法的不好的事情。所以我想出了这个解决方案: 只是通过聚合创建实体,毕竟我的聚合被注入了一个存储库,我可以在我的测试中模拟/存根,这样我就可以确保创建的所有实体都有一个有效的ID。 – 2009-11-03 23:15:05

-1

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

0

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

让你的数据库表标识主键列:

CREATE TABLE dbo.sample (
id int primary key identity(1,1), 
... 
... 
...) 

地图你的实体是这样的:

<id name="ID" column="id"> 
<generator class="identity" /> 
</id> 

主键会自动通过数据库时保存新生成的实体首次。 IDENTITY(1,1)的意思是“给新的行一个身份从'1'开始,然后每个后续的行增加1”:所以1,2,3,4,5,6,7

+0

我让nhibernate在保存时生成主键。但是,在视图方面存在识别对象的问题,当两个对象只有我的参考不同时。你如何处理? – Mank 2009-11-06 05:11:32

+0

覆盖对象中的GetHashCode()和Equals() – reach4thelasers 2009-11-06 18:05:12

相关问题