Я пытался обернуть голову вокруг подклассов и присоединился к подклассам в Fluent nHibernate в течение нескольких дней без каких-либо успехов.Я посмотрел вики, но, похоже, она не дает мне достаточно информации, и поиск в Google возвращает мне старые результаты, которые используют устаревший код или, по-видимому, не связаны между собой.
Я просто хочу простой пример, если это вообще возможно
У меня есть четыре таблицы, которые выглядят следующим образом:
+--------------+ +---------------+ +---------------+
| Animal | | AnimalType | | Reptile |
+==============+ +===============+ +===============+
| Id | | Id | | AnimalId |
| AnimalTypeId | | Description | | TongueLength |
| version | +---------------+ +---------------+
+--------------+
Таким образом, таблица Animal имеет FK, которыйссылается на таблицу AnimalType, таблицу поиска, содержащую всего 1 Id, в качестве теста,
1 = Reptile
Идея состоит в том, что столбец AnimalTypeId - это мой столбец дискриминатора, который разделяет мои подклассы,и каждая из таблиц животных (Reptile) имеет первичные ключи FK, которые ссылаются на Id из таблицы Animal в зависимости от его AnimalTypeId.
Так что мои классы C # выглядят так
public class Animal
{
public virtual int Id {get;set;}
public virtual AnimalType AnimalType {get;set;}
public virtual int Version {get; protected set;}
}
public class AnimalType
{
public virtual int Id {get;set;}
public virtual string Description {get;set;}
}
public class Reptile : Animal
{
public virtual int AnimalId {get;set;}
public virtual float TongueLength {get;set;}
}
Какмне сопоставить это как подкласс для таблицы?
Вот мое текущее отображение.
public class AnimalMap : ClassMap<Animal>
{
public AnimalMap()
{
Table("Animal");
Id(x => x.Id);
DiscriminateSubClassesOnColumn("AnimalTypeId",0)
.AlwaysSelectWithValue();
Version(x => x.Version);
}
}
public class ReptileMap: SubclassMap<Reptile>
{
public ReptileMap()
{
DiscriminatorValue(1);
Table("Reptile");
KeyColumn("AnimalId");
Map(x => x.TongueLength);
}
}
public class AnimalTypeMap : ClassMap<AnimalType>
{
public AnimalTypeMap ()
{
Table("AnimalTypeMap");
Id(x => x.Id);
Map(x => x.Description);
}
}
Это почти работает, просто не похоже, что подкласс происходит из другой таблицы.Ниже показано отображение HBM.
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="true">
<class xmlns="urn:nhibernate-mapping-2.2" discriminator-value="0" schema="dbo" name="NamespaceDefault.Animal, SolEntity, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="Animal">
<id name="Id" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Id" />
<generator class="identity" />
</id>
<discriminator type="Int32" force="true">
<column name="AnimalTypeId" />
</discriminator>
<version name="Version" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Version" />
</version>
<subclass name="NamespaceDefault.Reptile, SolEntity, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="1">
<property name="TongueLength" type="System.Float, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="TongueLength" />
</property>
</subclass>
</class>
</hibernate-mapping>
edit: Ранее была проблема с дублирующимися объектами.Решение связано в следующем комментарии.