我有一个基本结构。 User对象和UserDetails对象。 User表具有用于生成UserId的标识主键,然后我还想为此UserId保存UserDetails对象。单独执行此操作很容易,但是我试图找到一种方法,如果我可以一次性完成,因为User类包含对UserDetails对象的引用。例如
用户u =新用户(){Name =“me”,年龄= 17,UserDetails = new UserDetails(){Detail1 = 1}};
所以我要做的就是传递用户对象,然后包含对其他相关子信息的基于对象的引用(我已经为这个例子大大简化了它,但是有几个类似于UserDetails的类,比如UserMatchConfiguration等并且每个领域都有很多领域)
我希望能够在代码中构建对象,或者让它传递并修改,然后在父User对象上调用save,然后保存所有相关对象。到目前为止,我已经使用一对一映射实现了这一点并保存了级联,但问题是当你创建一个新对象时,当我希望它首先保存User类时,所有相关类的UserId都设置为零,然后将生成的UserId传播到所有相关类,然后保存它们。
到目前为止,映射如下。
<class name="User" table="[User]">
<id name="UserId" unsaved-value="0">
<generator class="identity" />
</id>
<property name="FirstName" />
<property name="LastName" />
<property name="EmailAddress" />
<property name="DateOfBirth" />
<property name="Gender" />
<property name="PostcodePartOne" />
<property name="PostcodePartTwo" />
<many-to-one name="UserLocation" column="UserLocationId" />
<property name="DateJoined" />
<property name="LastLoggedOn" />
<property name="Status"/>
<property name="StatusNotes" />
<bag name="Photos" order-by="DisplayOrder asc" inverse="true" lazy="false" cascade="all">
<key column="UserId" />
<one-to-many class="UserPhoto" />
</bag>
<bag name="Interests" inverse="true" lazy="false" cascade="all">
<key column="UserId" />
<one-to-many class="UserMatchInterest" />
</bag>
<bag name="Preferences" inverse="true" lazy="false" cascade="all">
<key column="UserId" />
<one-to-many class="UserPreference" />
</bag>
<one-to-one name="Profile" class="UserProfile" cascade="save-update" />
<one-to-one name="MatchCriteria" class="UserMatchCriteria" />
<one-to-one name="MatchLifestyle" class="UserMatchLifestyle" />
<property name="LastUpdated" />
</class>
正如你所看到的那样,我现在正在尝试使用Profile对象试图让它运行起来。我怎样才能让主User对象首先保存,然后将UserId传递给其他类,因为它们都将它作为主键使用?
我再次无法进行级联保存,然后在每个子类上手动设置UserId并单独保存,但我试图在一次调用中完成。
答案 0 :(得分:0)
我会说你几乎就在那里。您的user
类映射似乎是正确的,因此我怀疑是UserProfile
。
NHibernate正好支持这种关系,它是one-to-one
映射(正如你所尝试的那样)。虽然我们看不到 UserProfile 映射,但让我们按照文档扩展它:
UserProfile
hbm
<class name="UserProfile" table="[UserProfile]">
<id name="UserProfileId" column="UserId">
<generator class="foreign">
<param name="property">User</param>
</generator>
</id>
...
<one-to-one name="User" class="User" constrained="true"/>
</class>
UserProfile需要以下属性:
public class UserProfile
{
public virtual int UserProfileId { get; set; }
public virtual User User { get; set; }
...
}
在插入之前,我们必须连接两端(这是非常重要的一步):
user.Profile = profile;
profile.User = user;
如果user.hbm.xml
中的级联映射如下所示:
<one-to-one name="Profile" class="UserProfile" cascade="all" />
我们只能保存 user
,NHiberante会保留所有其他实体(在正确的范围内)。无论如何都不需要处理ID。