2

我理解并接受身份生成器会破坏工作单元,因为它需要在事务实际提交时先插入,如http://fabiomaulo.blogspot.com/2008/12/identity-never-ending-story 中所述。 .html _ 我知道替代方案以及为什么它们更好(与手头的问题有关,一般来说)。

我的问题是为什么实现存在,以及这些问题是否会影响 EF(纯粹的好奇心)。我见过的唯一真正的理由是:“NHibernate 需要身份,因为会话中的每个实体(它们被称为“持久实体”)都需要被识别。身份通常也用于确定数据库中是否已经存在记录(未保存的值)。”

但是,为什么它必须立即具有价值?为什么它不能推迟 INSERT 直到提交发生,提交,检索值,并根据返回的身份更新实体,然后插入/更新/不管它们?

不太重要的问题:EF 是否遇到同样的问题?我知道 ISession 是一个合适的 UoW 实现;EF 没有实现 UoW 模式,还是有不同的方法来处理这个问题,如果有,它是什么?

4

1 回答 1

3

我不会确切地告诉您为什么 NHibernate 中没有延迟插入,但我猜 NHibernate 只是在您将其放入会话时立即需要真实的实体身份。

EF 不使用这种方法,但这并不意味着 EF 方法更好。首先,EF 没有内置对身份生成器的支持。您可以实现自己的,但由于 NH 试图避免的问题,它可能有点挑战性。

ORM 工具实现身份映射,它们要求唯一标识每个实体。NH 可能立即使用真实身份,而 EF 可以推迟身份定义并使用一些临时密钥。当在数据库中定义真实身份时使用此临时键 - 这意味着IDENTITYMS SQL Server 中的列。EF只有在将记录插入数据库并查询后才知道真实身份SCOPE_IDENTIY()。当 EF 收到真实密钥时,它会更新实体及其所有关系 (FK) 以反映真实身份。

这也是该方法的最大缺点 - EF 必须在单独的往返中将每条记录插入到数据库以获取其主键值(无论如何,EF 不支持命令批处理)。在这里,您会发现与 NH 最大的区别,它能够使用生成器预生成身份并将这些 DML 命令批处理到单个往返数据库。

当您开始使用 EF 4.0 中引入的 FK 属性时,在 EF 中使用临时键会产生另一个副作用。一旦使用了 FK 属性,您必须将 PK 显式设置为某个唯一的临时值,否则插入两条具有关系的记录将失败并出现异常(您将拥有两个具有默认键值的实体,并且 FK 属性将无法定义哪个是正确的主体)。

EF 旨在使用数据库生成的密钥,而 NH 更喜欢应用程序生成的密钥。

于 2012-07-10T13:25:41.003 回答