2010-12-31 2 views
1

У меня возникли проблемы, отображающую следующее NHibernate:Как сопоставить эти отношения в nhibernate 3.0?

У меня есть две таблицы (это наследие и не могут быть изменены):

 
     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 является ForeignKey значение 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 к получите NamePartAssemblyItem.

Если это 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 для присоединиться к части/tblParts?

ответ

2

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

+0

Спасибо за ответ. Я уточнил, что мне нужно сделать. – Kev

+0

Я думаю, что понял. Это запутанно, вы спрашиваете о сопоставлении свойства name, это не то, что вам нужно. Проблема заключается в том, что tblPartAssemblyItems.PartID является частью первичного ключа, а также внешнего ключа, верно? Ну, я не думаю, что это возможно. В любом случае, отображение только внешнего ключа означает использование элемента отображения , а в вашем коде у вас будет ссылка на Part вместо целого числа PartID. Проверьте, можете ли вы использовать это внутри <составного-id>. – fejesjoco

+0

Хорошо ... ваш комментарий о том, что ссылка на детали погружена в ... Я думаю, что у меня есть рабочее решение. Благодарю. ps: Вы должны отредактировать свой комментарий в своем ответе. – Kev

0

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

Кроме того, эта статья Ayende завершила круг:

NHibernate Mapping - one-to-one

Смежные вопросы