NHibernate 为新实体生成 INSERT 和 UPDATE
Posted
技术标签:
【中文标题】NHibernate 为新实体生成 INSERT 和 UPDATE【英文标题】:NHibernate generates INSERT and UPDATE for new entity 【发布时间】:2013-11-16 16:42:22 【问题描述】:我有一个使用 Hilo 生成的带有 Id 列的实体。 我有一个事务,创建一个新实体并调用 SaveOrUpdate() 以获取 Hilo 生成的实体 ID(我需要将该 ID 写入另一个数据库)。
稍后,在同一个事务中,我更新了新实体,只是简单地更新了一个简单的属性,最后我再次调用了 SaveOrUpdate()。
我看到生成的 SQL 命令首先是 INSERT,然后是 UPDATE,但我想要的只是一个带有实体最终详细信息的 INSERT。那可能吗?我是不是做错了什么?
编辑:添加代码示例
这是一个非常简化的伪代码示例:
Person newPerson = new Person(); // Person is a mapped entity
newPerson.Name = "foo";
_session.SaveOrUpdate(newPerson); // generates INSERT statement
newPerson.BirthDate = DateTime.Now;
_session.SaveOrUpdate(newPerson); // generates UPDATE statement
// assume session transaction was opened before and disposed correctly for sake of simplicity
_session.Transaction.Commit();
【问题讨论】:
【参考方案1】:关键是使用像 NHibernate 这样的 ORM 工具,我们以不同的方式工作,然后我们使用 ADO.NET。
虽然 ADO.NET Commands
和它们的 Execute()
方法系列会导致在 DB 服务器上立即执行 SQL 语句……但 NHibernate 却截然不同。
我们正在与ISession
合作。会话,可以被认为是内存中的 C# 集合。所有Save()
、SaveOrUdpate()
、Update()
、Delete()
... 调用都是针对该对象表示执行的。没有执行 SQL 命令,在调用这些方法时,目前没有 低级 ADO.NET 调用。
抽象允许 NHibernate 优化最终的 SQL 语句批处理...基于在 ISession
中收集的所有信息。这就是为什么,如果使用 Session
,您将永远不会看到 INSERT、UPDATE,除非我们明确调用神奇的 Flush()
或完全更改 FlushMode。
在那种情况下(调用Flush()
),我们想说:NHibernate 我们已经足够聪明了,现在是执行命令的时候了。在其他情况下,通常将其留在 NHibernate 上就足够了...
请看这里: - 9.6. Flush
【讨论】:
我了解 Flush() 的机制,我只是期望在同一会话中插入实体然后更新的优化行为,只会生成一个带有最终值的 INSERT 语句实体。 这一切都取决于您拥有的映射。如果 NHibernate 可以在单个插入中做到这一点,那么在大多数情况下都会以这种方式完成。但老实说......如果你在一个事务中并且在一个会话中...... Save() 就足以被调用。因为那时,在您使用瞬态对象之前,所有更改仍会应用到那个“未保存”的对象中。 fulsh 将保存最终版本。如果有显式调用 insert.. 这可能意味着,一些其他依赖项会强制执行该操作(关系)等。以上是关于NHibernate 为新实体生成 INSERT 和 UPDATE的主要内容,如果未能解决你的问题,请参考以下文章
ORM篇——使用NHibernate配置对象实体的一些小问题
Fluent NHibernate 自动映射:一对多实体,多对多后端?