为什么NHibernate首先插入然后更新集合的元素?

时间:2010-01-08 16:55:20

标签: sql nhibernate

我不确定这是不正确的行为还是在我身边做错了什么:

我有一个非常简单的亲子关系

public class SubmittedBatch
{
    public virtual Guid Id { get; set; }
    public virtual IList<SubmittedBatchParameter> Parameters { get; private set; }
}

public class SubmittedBatchParameter
{
    public virtual string Value { get; set; }
}

使用FluentNH配置如下:

mapping.HasMany<SubmittedBatchParameter>(sb => sb.Parameters).Cascade.All();

我做了一些简单的事情,比如在Parameters集合中添加新元素,然后在父元素上调用SaveOrUpdate

查看SQL语句的跟踪,我得到一个插入:

INSERT INTO [SubmittedBatchParameter]
           (Value)
VALUES     ('Disabled' /* @p0 */)
select SCOPE_IDENTITY()

然后更新:

UPDATE [SubmittedBatchParameter]
SET    SubmittedBatch_id = '209971b7-c311-46bd-b989-9cf80113654c' /* @p0_0 */
WHERE  Id = 39 /* @p1_0 */

为什么NH只是在指定Guid的情况下进行插入? 这是正确的,还是我做错了什么?

谢谢 西蒙

1 个答案:

答案 0 :(得分:5)

您尚未明确映射反向父关系。因此,NHibernate知道保存SubmittedBatch_id列值的唯一方法是保存对象。它不能同时保存两个对象,所以它的作用是保存子节点,然后在保存父节点时保存关系。

事实上,即使您要映射关系的两个方向,您仍然必须通过将另一个标记为“反向”关系来指定哪个是“主”。然后通过保存主端来更新该字段。

因此,如果您要在SubmittedBatch类中映射SubmittedBatchParameter属性,请将其映射为“master”(即使用Fluent中的.Inverse将集合映射设置为反向),以及然后设置当你将参数添加到批处理时,你会看到你期望的插入。

这就是我的意思:

public class SubmittedBatch
{
    public virtual Guid Id { get; set; }
    public virtual IList<SubmittedBatchParameter> Parameters { get; private set; }
}

public class SubmittedBatchParameter
{
    public virtual SubmittedBatch SubmittedBatch { get; set; }
    public virtual string Value { get; set; }
}

然后在子映射中:

HasMany<SubmittedBatchParameter>(sb => sb.Parameters).Inverse();

并在父映射中:

References(sbp => sbp.SubmittedBatch);