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

Cod*_*ber 1 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; }
}
Run Code Online (Sandbox Code Playgroud)

并使用FluentNH配置如下:

mapping.HasMany<SubmittedBatchParameter>(sb => sb.Parameters).Cascade.All();
Run Code Online (Sandbox Code Playgroud)

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

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

INSERT INTO [SubmittedBatchParameter]
           (Value)
VALUES     ('Disabled' /* @p0 */)
select SCOPE_IDENTITY()
Run Code Online (Sandbox Code Playgroud)

然后更新:

UPDATE [SubmittedBatchParameter]
SET    SubmittedBatch_id = '209971b7-c311-46bd-b989-9cf80113654c' /* @p0_0 */
WHERE  Id = 39 /* @p1_0 */
Run Code Online (Sandbox Code Playgroud)

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

谢谢西蒙娜

Dav*_*d M 5

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

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

因此,如果您要SubmittedBatchSubmittedBatchParameter类中映射属性,请将其映射为"主"(即使用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; }
}
Run Code Online (Sandbox Code Playgroud)

然后在子映射中:

HasMany<SubmittedBatchParameter>(sb => sb.Parameters).Inverse();
Run Code Online (Sandbox Code Playgroud)

并在父映射中:

References(sbp => sbp.SubmittedBatch);
Run Code Online (Sandbox Code Playgroud)