NHibernate保存相关实体

时间:2012-11-22 17:20:07

标签: c# nhibernate one-to-one

我有一个基本结构。 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并单独保存,但我试图在一次调用中完成。

1 个答案:

答案 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。