如何在nhibernate 3.0中映射此关系?

时间:2010-12-31 13:20:08

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

我无法在NHibernate中映射以下内容:

我有两个表(这些是遗留的,不能更改):

       tblParts
       =======
 + --- ID            int identity(1,1)  [----------+
 |     Name          varchar(50)                   |
 |     PartTypeID    int                           |
1:*     Quantity      int                          |
 |                                                 |
 |     tblPartAssemblyItems                       *:1
 |     ====================                        |
 +-]   PartID              int (PK)                |
       AssemblyItemPartID  int (PK) ---------------+
       Status              int
       Coding              varchar(50)

tblParts.PartTypeID告诉我们部件的类型。有几个可能的值。有一个特殊情况:

  • PartTypeID = 0 - 它告诉我们此部分由tblPartAssemblyItems中列出的0个或更多子部分组成。
  • PartTypeID = 1 - 这是一个完整的独立部分
  • PartTypeID = 2 - 此部分用于构成其他部分

PartID是外键值tblParts.IDAssemblyItemPartID tblParts引用了tblParts.ID中的部分记录。

子部分永远不会由其他子部分组成,这样可以将嵌套保持在一个深度。

PartID + AssemblyItemPartID形成复合主键。

在我的代码中,我有:

public class Part
{
  public virtual int ID { get; set; }
  public virtual string Name { get; set; }
  public virtual int PartTypeID { get; set; }
  public virtual int Quantity { get; set; }
  public virtual IList<PartAssemblyItem>
}

public class PartAssemblyItem
{
  public virtual int PartID { get; set; }
  public virtual int AssemblyItemPartID { get; set; }
  public virtual int Status { get; set; }
  public virtual string Coding { get; set; }
  public virtual string Name { get; set; }

  public override bool Equals(object obj) { .. snipped .. }
  public override int GetHashCode() { .. snipped .. }
}

我的基本映射工作正常:

<class name="Part" table="tblParts">
  <id name="ID">
    <column name="ID" sql-type="int" not-null="true"/>
    <generator class="identity" />
  </id>
  <property name="Name"/>
  <property name="PartTypeID"/>
  <bag name="PartAssemblyItems">
    <key column="PartID"/>
    <one-to-many class="PartAssemblyItem"/>
  </bag>
</class>

<class name="PartAssemblyItem" table="tblPartAssemblyItems">
  <composite-id>
    <key-property name="PartID" column="PartID"/>
    <key-property name="AssemblyItemPartID" column="AssemblyItemPartID"/>
  </composite-id>
  <property name="Status" />
  <property name="Coding" />
  <property name="Name" />   <-- How do I map this?
</class>

但我不知道如何加入/回顾tblParts以获取Name的{​​{1}}。

如果这是T-SQL,我会做这样的事情来选择所有零件及其零件构成:

PartAssemblyItem

如何以“NHibernate”方式执行此操作,我可以使用HQL连接回Part / tblParts吗?

2 个答案:

答案 0 :(得分:2)

tblPartAssemblyItems没有Name列,因此不要映射它。如果你真的想在你的类中使用它,那么定义一个自定义的getter,它返回已连接实体的名称。

答案 1 :(得分:0)

有关Part的{​​{1}}引用PartAssemblyItem的评论帮助,我认为我已经解决了这个问题:

public class PartAssemblyItem
{
  public virtual int PartID { get; set; }
  public virtual int AssemblyItemPartID { get; set; }
  public virtual int Status { get; set; }
  public virtual string Coding { get; set; }
  // public virtual string Name { get; set; } <--- DELETED THIS
  // Then added this:
  public virtual Part Part { get; set; }

  public override bool Equals(object obj) { .. snipped .. }
  public override int GetHashCode() { .. snipped .. }
}

已配置的PartAssemblyItem.hbm.xml映射为:

<class name="PartAssemblyItem" table="tblPartAssemblyItems">
  <composite-id>
    <key-property name="PartID" column="PartID"/>
    <key-property name="AssemblyItemPartID" column="AssemblyItemPartID"/>
  </composite-id>
  <property name="Status" />
  <property name="Coding" />

  <!-- The magic happens here -->
  <many-to-one name="Part" class="Part" column="AssemblyItemPartID" />
</class>

所以现在我可以得到一份零件清单,然后看看它们的组成部分:

using(ISession session = partsDB.OpenSession())
{
  using (var tx = session.BeginTransaction())
  {
    IList<Part> parts = 
      session
      .CreateQuery("select p from Part as p where p.PartTypeID <> 2")
      .List<Part>();

    foreach (Part part in parts)
    {
      Console.WriteLine("{0} - {1}", part.ID, part.Name);

      foreach (PartAssemblyItem subPart in part.PartAssemblyItems)
      {
        Console.WriteLine("--> {0} - {1}", subPart.Part.ID, subPart.Part.Name);
      }
    }
  }
}

Ayende的这篇文章也完成了这个圈子:

  

fejesjoco