Nhibernate,更新孩子给了新的父母

时间:2013-09-08 13:35:40

标签: c# nhibernate

我是nhibernate的新手。当我正常更新记录(没有孩子)时,我只需创建一个新对象,设置旧ID,更改所需值并更新记录。这很有效。

当我对我的孩子做同样的事情时,我需要设置父记录,否则我会得到一个 无法执行批处理命令。[SQL:SQL不可用]错误。

为此,我创建了一个新的父级并设置了父级的Id。我希望这会成功。没有抛出异常,但现在我在数据库中获得了一条新的父记录。

我是否应该在更新前始终阅读要更新的对象,还是有其他方法可以执行此操作? (更新前阅读将花费一些性能)

1 个答案:

答案 0 :(得分:3)

你正在与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: 误读你的帖子。你确实说过&#34;在更新之前阅读将花费一些性能&#34;。我认为这里的性能损失并不重要,除非代码用于绝对关键的目的。

编辑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访问父记录的数据库,而是给我一个未初始化的代理。

所以有可能实现你想要的,但我不认为这样做是好的,迟早这段代码会回来咬你,因为这段代码会产生当对象模型变得更复杂时,会出现一些意想不到的行为。