2012-03-14 50 views
3

我有一个用户对象,其中一个属性包含一个Photos属性,它是IList类型。Nhibernate - 从属表保存对象

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

表用户{的userid长NOT NULL .......} 表UserPhoto {PHOTOID长NOT NULL,用户ID不长空引用[用户] .UserId ........}

所以你不能在没有相应用户行的userphoto中插入一行。

我想要做的就是在代码中建立一个用户对象,添加一个UserPhoto对象的Ilist(它必须包含一个空白的用户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(用户)的用户对象,它抛出一个错误说外键约束失败。所以,即时猜测它试图插入用户照片列表之前的用户表,或其不设置新生成的用户ID属性的照片,并试图用空的用户ID保存它们。

您是否必须在映射中额外添加一些内容以显示这是一个外键列及其应用,因此nhibernate知道如何以正确的顺序插入相关行,以便在一次插入中完成此操作?

回答

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> 

逆=真正加入到照片袋

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

也改变了用户ID元素的多到一个用户元素

+0

好的感谢您的链接,是有道理的。我仍然得到错误,但从你张贴的链接我得到的印象我需要在子女声明映射?如果您在上面看到我的UserPhoto声明,那么只需将UserId映射为属性即可。这是问题吗?在UserPhoto声明中需要做什么才能让其了解FK关系?我试着在UserId上做一个简单的Many to One,但它说:“来自表UserPhoto的关联指的是一个未映射的类:System.Int32” – NZJames 2012-03-14 15:33:07

+0

如果使用inverse = true,则需要在代码中管理双方的关系 - 请参阅我的答案进一步的细节。 – 2012-03-14 15:38:46

+0

我已经更新了答案。尝试将UserId的属性引用更改为多对一的用户映射,并将UserPhoto类更改为 – reach4thelasers 2012-03-14 15:48:41

0

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

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

你要么需要在映射添加逆=“真”的照片集

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

,或者你将需要用户ID列可为空的照片表。

如果你做的第一选择,你需要配置的对象自己之间的关系:

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

随着逆=“真”集,NH将插入用户,更新基于身份的用户ID值,然后插入每张照片,将每个插入的用户标识设置在照片表中。

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