每个层次结构和自引用表的Nhibernate表

时间:2011-06-06 15:36:59

标签: nhibernate

我有这样的问题。

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Altkom.Model" namespace="Altkom.Model">
  <class name ="Employee" table="Employee" discriminator-value="Employee">
    <id name ="EmployeeId" column="EmployeeId">
      <generator class="uuid.hex" />
    </id>
    <discriminator column="Discriminator" not-null="true" type="System.String"/>
    <property name="FirstName" column="FirstName" not-null="true" />
    <property name="LastName" column="LastName" not-null="true" />
    <property name="BirthDate" column="BirthDate" not-null="true"/>
    <property name="Sex" column="Sex" not-null="true" />
    <!--<property name="ManagerId" column="ManagerId"/>-->
    <component name="Address" class="Altkom.Model.Address, Altkom.Model">
      <property name="City" column="City" not-null="true" />
      <property name="Street" column="Street" not-null="true" />
      <property name="Country" column="Country" not-null="true" />
      <property name="ZipCode" column="ZipCode" not-null="true" />
    </component>
    <bag name="Projects" table="EmployeeProject" lazy="true">
      <key column="EmployeeId"/>
      <many-to-many column="ProjectId" class="Project" />
    </bag>
    <bag name="JobHistories" lazy="false">
      <key column="EmployeeId"/>
      <one-to-many class="JobHistory"/>
    </bag>
    <many-to-one name ="Manager" class="Altkom.Model.Manager, Altkom.Model" column="ManagerId"/>
    <subclass name="Manager" discriminator-value="Manager">
      <!--<many-to-one name ="Employee" class="Altkom.Model.Employee, Altkom.Model" column="EmployeeId" not-null="false" cascade="all-delete-orphan" lazy="false"/>-->
      <bag name="Subordinates" lazy="false" inverse="true" cascade="all-delete-orphan">
        <key column="ManagerId"/>
        <one-to-many class="Employee"/>
      </bag>
      <property name="RoomNumber" column="RoomNumber"/>
    </subclass>
  </class>
</hibernate-mapping>

表结构是:

CREATE TABLE [dbo].[Employee](
    [EmployeeId] [nvarchar](255) NOT NULL,
    [Discriminator] [nvarchar](255) NOT NULL,
    [FirstName] [nvarchar](255) NOT NULL,
    [LastName] [nvarchar](255) NOT NULL,
    [BirthDate] [datetime] NOT NULL,
    [Sex] [int] NOT NULL,
    [City] [nvarchar](255) NOT NULL,
    [Street] [nvarchar](255) NOT NULL,
    [Country] [nvarchar](255) NOT NULL,
    [ZipCode] [nvarchar](255) NOT NULL,
    [ManagerId] [nvarchar](255) NULL,
    [RoomNumber] [nvarchar](255) NULL,
PRIMARY KEY CLUSTERED 
(
    [EmployeeId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[Employee]  WITH CHECK ADD  CONSTRAINT [FK74988DB23FED7E5D] FOREIGN KEY([ManagerId])
REFERENCES [dbo].[Employee] ([EmployeeId])
GO

ALTER TABLE [dbo].[Employee] CHECK CONSTRAINT [FK74988DB23FED7E5D]
GO

我应该怎么做才能使Subordinates的财产运作良好。 谢谢你的任何建议。

1 个答案:

答案 0 :(得分:0)

我们在NH应用程序中使用了一个非常相似的结构。我可以在您的映射中看到的差异是:

1)我们不嵌套类定义 2)我们在多对一元素上指定fetch ='select' 3)我们在bag元素上使用lazy ='true'

因此,重新设计映射将如下所示:

<class name ="Employee" table="Employee" discriminator-value="Employee">
   ...
   <many-to-one name ="Manager" fetch="select" class="Altkom.Model.Manager, Altkom.Model" column="ManagerId"/>
   ...
</class>
<subclass name="Manager" extends="Employee" discriminator-value="Manager">
   <bag name="Subordinates" lazy="true" inverse="true" cascade="all-delete-orphan">
     <key column="ManagerId"/>
     <one-to-many class="Employee"/>
   </bag>
   ...
</subclass>

[顺便说一句,我怀疑你是否真的想要使用Manager的子类。有人晋升后会发生什么?或者你只是想分配一个初级下属?您将需要更改此对象的类型,并可能重新创建行并更新所有关联的记录,我通常只使用不同的类,其中存在相当强的类型不变性]