Как мне сопоставить эти отношения в nhibernate 3.0? - PullRequest
1 голос
/ 31 декабря 2010

У меня проблемы с отображением в 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 - это говорит нам, что эта часть состоит из 0 или более частей, перечисленных в tblPartAssemblyItems.
  • PartTypeID = 1 - это полная автономная часть
  • PartTypeID = 2 - эта часть используется для создания других частей

PartID - значение иностранного ключа tblParts.ID. AssemblyItemPartID ссылается на запись детали в 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 из PartAssemblyItem.

Если бы это был T-SQL, я бы сделал что-то вроде этого, чтобы выбрать все детали и их состав:

SELECT p.ID, p.Name, p.PartTypeID, i.AssemblyItemPartID, 
       i.Status, i.Coding, 
       p2.Name AS AssemblyItemPartName
FROM tblParts p
LEFT JOIN tblPartAssemblyItems i ON p.ID = i.PartID
-- This join here to get the subassembly name
LEFT JOIN tblParts p2 ON i.AssemblyItemPartID = p2.ID
WHERE p.PartTypeID <> 2 
ORDER BY p.ID

Как мне это сделать "NHibernate", могу ли я использовать HQL для присоединения к Part / tblParts?

Ответы [ 2 ]

2 голосов
/ 31 декабря 2010

tblPartAssemblyItems не имеет столбца Name, поэтому не отображайте его. Если вы действительно хотите использовать его в своем классе, определите пользовательский метод получения, который возвращает имя объединенной сущности.

0 голосов
/ 31 декабря 2010

С помощью комментария fejesjoco о наличии ссылки Part в 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);
      }
    }
  }
}

Также эта статья Айенде завершила круг:

NHibernate Mapping - один-к-одному

...