Nhibernate:映射有条件的多对多关系?

时间:2012-01-29 08:30:05

标签: c# asp.net nhibernate nhibernate-mapping

我有以下对象模型:

public class Organizer
{
    private int id;

    public virtual int Id
    {
        get { return id; }
        set { id = value; }
    }

    private string fullName = "";

    public virtual string FullName
    {
        get { return fullName; }
        set { fullName = value; }
    }

    private List<Email> emails = new List<Email>();

    public virtual List<Email> Emails
    {
        get { return emails; }
        set { emails = value; }
    }
}


public enum EmailType
{
    Primary, Secondary
}

public class Email
{
    private int iD;

    public virtual int ID
    {
        get { return iD; }
        set { iD = value; }
    }
    private string emailAddress = "";

    public virtual string EmailAddress
    {
        get { return emailAddress; }
        set { emailAddress = value; }
    }
    private EmailType emailType = EmailType.Primary;

    public virtual EmailType EmailType
    {
        get { return emailType; }
        set { emailType = value; }
    }

    private List<Organizer> organizers;

    public virtual List<Organizer> Organizers
    {
        get { return organizers; }
        set { organizers = value; }
    }
}

我有以下数据库架构:

CREATE TABLE [dbo].[EmailAddresses](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [EmailAddress] [nvarchar](550) NULL
)

CREATE TABLE [dbo].[Organizers](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [FullName] [nvarchar](550) NULL
)

CREATE TABLE [dbo].[Organizers_PrimaryKeys](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [PrimaryKeyID] [int] NULL,
    [PrimaryKeyTypeID] [int] NULL,
    [OrganizerID] [int] NULL
)

现在,我遇到了严重的问题,想弄清楚如何用nhibernate(不流利的nhibernate)来映射它。基本上,我希望它映射为当我执行“session.Save(anOrganizer)”时,数据有时会写入两个表,有时会写入三个表。例如,假设我们有OrganizerA,他有三封电子邮件:email_1,email_2和email_3。 email_1有EmailType.Primary,而另外两个有EmailType.Secondary。因此,当我们保存OrganizerA时,会发生以下情况:

  1. OrganizerA的详细信息将写入表格组织者
  2. email_1,email_2和email_3都会写入EmailAddresses表(如果它们尚不存在)
  3. 在Organizers_PrimaryKeys表中创建了一个新行,其中email_1的id被写为PrimaryKeyID,OrganizerA的id被写为OrganizerID(不用担心PrimaryKeyTypeID。我稍后会详细说明)。
  4. 那么我如何映射这种关系呢?到目前为止,我有以下内容:

    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                       assembly="BLL"
                       namespace="BusinessLogic">
    
      <class name="Organizer" table="Organizers">
        <id name="Id">
          <column name="ID"/>
          <generator class="native" />
        </id>
        <property name="FullName">
          <column name="FullName"/>
        </property>
        <bag name="Emails" table="Organizers_PrimaryKeys" inverse="false" cascade="all" lazy="true" >
          <key column="Id"/>
          <many-to-many class="Email" />
        </bag>
      </class>
    </hibernate-mapping>
    
    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                       assembly="BLL"
                       namespace="BusinessLogic">
    
      <class name="Email" table="EmailAddresses">
        <id name="ID">
          <column name="ID"/>
          <generator class="native" />
        </id>
        <property name="EmailAddress" unique="true" type="string" >
          <column name="EmailAddress"/>
        </property>
    
      </class>
    </hibernate-mapping>
    

    我不知道在Email.hbm.xml中放什么来完成这种“有条件的”多对多关系。

2 个答案:

答案 0 :(得分:2)

您需要将主要和次要电子邮件分隔为两个不同的对象,因为它们不是同一类型的实体。添加Organizer类与PrimaryEmail的一对一关系,并保留当前的多对多SecondaryEmail列表。

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
               assembly="BLL"
               namespace="BusinessLogic">

   <class name="Organizer" table="Organizers">
   <id name="Id">
      <column name="ID"/>
      <generator class="native" />
   </id>
   <property name="FullName">
      <column name="FullName"/>
   </property>
   <one-to-one name="PrimaryEmail" class="PrimaryEmail" />
   <bag name="Emails" table="EmailAddresses" inverse="false" cascade="all" lazy="true" >
     <key column="Id"/>
     <many-to-many class="SecondaryEmail" />
   </bag>
  </class>

  <class name="PrimaryEmail" table="Organizers_PrimaryKeys">
    <id name="ID">
      <column name="ID"/>
      <generator class="native" />
    </id>
    <property name="EmailAddress" unique="true" type="string" >
      <column name="EmailAddress"/>
    </property>
  </class>

  <class name="SecondaryEmail" table="EmailAddresses">
    <id name="ID">
      <column name="ID"/>
      <generator class="native" />
    </id>
    <property name="EmailAddress" unique="true" type="string" >
      <column name="EmailAddress"/>
    </property>
  </class>

答案 1 :(得分:0)

email_1,email_2和email_3作为属性

附加到Organizers表