首页 文章

Nhibernate - 使用从属表保存对象

提问于
浏览
3

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

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

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

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

我想要做的是在代码中 Build 一个用户对象,添加一个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

    试试这个:

    <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添加到Photos包中

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

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

  • 0

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

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

    您需要在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语句 .

相关问题