我是新来的休眠。当我通常更新记录(没有子项)时,我只是创建一个新对象,设置旧 ID,更改所需值并更新记录。这行得通。
当我对我的孩子做同样的事情时,我需要设置父记录,否则我得到一个无法执行批处理命令。[SQL:SQL 不可用]错误。
所以要做到这一点,我创建了一个新的父级并设置了父级的 ID。我希望这能解决问题。没有抛出异常,但现在我在我的数据库中获得了一条新的父记录。
在更新之前我应该总是阅读要更新的对象还是有其他方法可以做到这一点?(更新前阅读会消耗一些性能)
我是新来的休眠。当我通常更新记录(没有子项)时,我只是创建一个新对象,设置旧 ID,更改所需值并更新记录。这行得通。
当我对我的孩子做同样的事情时,我需要设置父记录,否则我得到一个无法执行批处理命令。[SQL:SQL 不可用]错误。
所以要做到这一点,我创建了一个新的父级并设置了父级的 ID。我希望这能解决问题。没有抛出异常,但现在我在我的数据库中获得了一条新的父记录。
在更新之前我应该总是阅读要更新的对象还是有其他方法可以做到这一点?(更新前阅读会消耗一些性能)
您正在与 NHibernate 战斗。这不是更新内容的正确方法。与其自己实例化对象,不如让 NHibernate 这样做,让它从 DB 加载现有数据并将数据填充到对象中:
// do something
// this will create an object, and populate data from database:
var vehicle = session.Get<Vehicle>(vehicleId);
// change the owner:
vehicle.Owner = "John Smith";
编辑1:误读您的帖子。您确实说过“在更新之前阅读会消耗一些性能”。我认为这里的性能损失并不重要,除非代码用于绝对关键的目的。
编辑 2:在这种情况下需要考虑许多参数。因为你没有在这里发布你的映射和数据模型类,所以我不知道你的代码有什么问题,这是我有根据的猜测。如果我是你,我会使用这样的东西:
public class Child
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual Parent Parent { get; set; }
}
public class Parent
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
和映射:
<class name="Child">
<id name="Id" unsaved-value="0"><generator class="identity" /></id>
<property name="Name" />
<many-to-one name="Parent"/>
</class>
<class name="Parent">
<id name="Id" unsaved-value="0"><generator class="identity" /></id>
<property name="Name" />
</class>
要在不加载旧数据的情况下更新 Parent,这可行:
session.Update(new Parent { Id = parentId, Name = "Parent 1" });
这确实会生成一个 UPDATE 而没有 SELECT。现在,如果您知道孩子的 id、父母 id 和孩子的新名称,您可以更新孩子而不会产生任何 SELECT:
session.Update(
new Child
{
Id = childId,
Name = "new name",
Parent = session.Load<Parent>(parentId)
});
说明:通过使用 session.Load,我明确告诉 NHibernate 不要访问具有关键 parentId 的父记录的数据库,而是给我一个未初始化的代理。
所以有可能实现你想要的,但我认为这不是一件好事,迟早这段代码会回来咬你,因为当对象模型变得更加复杂时,这段代码会产生一些意想不到的行为。