【发布时间】:2010-09-24 11:15:57
【问题描述】:
无论它是否已经存在,我都需要向数据库写入一行。在使用 NHibernate 之前,这是通过存储过程完成的。该过程将尝试更新,如果没有行被修改,它将回退到插入。这很有效,因为应用程序并不关心记录是否存在。
使用 NHibernate,我发现的解决方案需要加载实体并修改它,或者删除实体以便插入新实体。应用程序必须关心记录是否已经存在。有办法解决吗?
身份证重要吗?
分配的 ID
该对象有一个关键字作为分配的 id,并且是表中的主键。
我了解 SaveOrUpdate() 将根据 Id 适当调用 Save() 或 Update() 方法。使用分配的 id,这将不起作用,因为 id 不是未保存的值。但是,可以将版本或时间戳字段用作指示符。实际上,这无关紧要,因为这仅反映内存中的对象是否与数据库中的记录相关联;它不指示该记录是否存在于数据库中。
生成的 ID
如果分配的 id 确实是问题的原因,我可以使用生成的 id 而不是关键字作为主键。这将避免 NHibernate 插入/更新问题,因为它总是会有效地插入。但是,我仍然需要防止重复的关键字。在关键字列上使用唯一索引,即使主键不同,它仍然会为重复关键字抛出异常。
另一种方法?
也许问题并不在于 NHibernate,而在于它的建模方式。与应用程序的其他领域不同,这更以数据为中心,而不是以对象为中心。很高兴 NHibernate 使它易于读/写并消除了存储过程。但是,不考虑现有值而简单地编写的愿望与对象身份模型的模型不太吻合。有没有更好的方法来解决这个问题?
【问题讨论】:
-
所以你知道, saveOrUpdate() 实际上确实尝试从 oracle 加载对象。不知道为什么它不适用于您分配的 id 而不是生成的,但只要您在一个会话中完成所有操作,就不会花费您任何额外的时间。
-
当对象在数据库中不存在时,我得到一个错误,说它无法更新对象。谷歌搜索发现 SaveOrUpdate() 不适用于分配的 ID。
-
我已经更新了问题以更详细地解释问题并提高了我对 NHibernate 的理解
标签: nhibernate insert-update overwrite upsert