Nhibernate - 使用从属表保存对象

时间:2012-03-14 14:43:50

标签: c# nhibernate

我有一个User对象,因为其中一个属性包含Photos属性,它是IList类型。

SQL数据库中的表由外键连接。即

表用户{userid long NOT NULL .......} 表UserPhoto {photoid long NOT NULL,userid long not null引用[User] .UserId ........}

因此,如果没有相应的用户行,则无法在userphoto中插入行。

我希望能够做的是在代码中构建一个User Object,添加一个Ilist of UserPhoto对象(必须包含一个空白用户ID,User对象也是如此,因为它尚未保存和创建通过身份插入)

我的映射如下

 <class name="User" table="[User]">
    <id name="UserId" column="Id">
      <generator class="identity" />
    </id>
    <bag name="Photos" order-by="DisplayOrder asc" cascade="all">      
      <key column="UserId" />
      <one-to-many class="UserPhoto" />
    </bag>
 </class>
<class name="UserPhoto" table="UserPhoto">
    <id name="PhotoId" column="Id">
      <generator class="identity" />
    </id>
    <property name="UserId" />
</class>

但是当我尝试用Nhibernate Session.Save(用户)保存User对象时,它会抛出一个错误,说外键约束失败。因此,我猜测它试图在用户表之前插入列表中的用户照片,或者它没有在照片中设置新生成的用户ID属性并尝试使用空用户ID保存它们。

你是否必须在映射中有额外的东西来表明这是一个外键列及其适用的内容,所以nhibernate知道如何以正确的顺序插入依赖行,所以我可以在一个插入中实现这一点?

3 个答案:

答案 0 :(得分:1)

试试这个:

 <class name="User" table="[User]">
    <id name="UserId" column="Id">
      <generator class="identity" />
    </id>
    <bag name="Photos" order-by="DisplayOrder asc" cascade="all" inverse="true">      
      <key column="UserId" />
      <one-to-many class="UserPhoto" />
    </bag>
 </class>
<class name="UserPhoto" table="UserPhoto">
    <id name="PhotoId" column="Id">
      <generator class="identity" />
    </id>
    <many-to-one name="User" property-ref="UserId" column="UserId"/>
</class>

Inverse = true添加到照片包

http://bchavez.bitarmory.com/archive/2007/10/06/nhibernate-and-inversetruefalse-attribute.aspx

还将UserId元素更改为多对一用户元素

答案 1 :(得分:0)

您需要将inverse="true"添加到包中,否则NHibernate会尝试插入后更新:

<bag name="Photos" order-by="DisplayOrder asc" cascade="all" inverse="true">      
  <key column="UserId" />
  <one-to-many class="UserPhoto" />
</bag>

答案 2 :(得分:0)

您需要在Photo集合的映射中添加inverse =“true”

<bag name="Photos" order-by="DisplayOrder asc" cascade="all" inverse="true">

或者你需要在Photo表中使UserID列可以为空。

如果您执行第一个选项,则需要自己配置对象之间的关系:

var user = new User();
var photo = new Photo();
photo.User = user;
user.Photos.Add(photo);

设置inverse =“true”后,NH将插入用户,根据身份值更新用户ID,然后在每张插页中插入照片表中的用户ID的每张照片。

如果没有inverse =“true”设置,NH将使用null用户ID插入照片,为插入的照片选择所有照片ID,然后发出更新以设置用户ID。这将导致生成额外的SQL语句。