Я использую отображение NHibernate 3.2 по коду / соглашению и у меня возникают проблемы с отображением простого наследования таблиц на иерархии.Мой базовый класс - LookupBase, и существует более дюжины классов, производных от этого базового класса.Я хотел бы, чтобы модель класса отображалась в одной таблице в базе данных со столбцом дискриминатора (столбец дискриминатора будет содержать имя соответствующего конкретного класса).
Базовый класс LookupBase находится в другомсборка из конкретных классов.
Вот как реализованы конкретные классы:
namespace ROWMobile.Domain
{
public class NotificationMethod : LookupBase
{
}
public class ContactMethod : LookupBase
{
}
public class ContactType : LookupBase
{
}
...
Как видите, в конкретных классах нет дополнительных свойств - они наследуют все свойства отLookupBase.
private HbmMapping GenerateMappings()
{
ConventionModelMapper relationalMapper = new ConventionModelMapper();
var baseLookupType = typeof(LookupBase);
relationalMapper.IsRootEntity((t, declared) => t.BaseType != null && (t.BaseType == typeof(object)));
relationalMapper.IsTablePerClassHierarchy((t, declared) =>
{
if (t == typeof(LookupBase))
{
return true;
}
return false;
});
var mapping = relationalMapper.CompileMappingFor(GetDomainEntities());
return mapping;
}
private static IEnumerable<Type> GetDomainEntities()
{
Assembly domainAssembly = typeof(Event).Assembly;
IList<Type> baseEntities = new List<Type>();
baseEntities.Add(typeof(LookupBase));
IEnumerable<Type> domainEntities = from t in domainAssembly.GetTypes()
where (IsSubclassOfRawGeneric(typeof(LookupBase), t)
&& !t.IsGenericType)
select t;
IEnumerable<Type> allEntities = domainEntities.Concat(baseEntities);
return allEntities;
}
static bool IsSubclassOfRawGeneric(Type generic, Type toCheck)
{
while (toCheck != null && toCheck != typeof(object))
{
var cur = toCheck.IsGenericType ? toCheck.GetGenericTypeDefinition() : toCheck;
if (generic == cur)
{
return true;
}
toCheck = toCheck.BaseType;
}
return false;
}
Я называю приведенный выше код следующим образом:
HbmMapping generatedMappings = GenerateMappings();
System.Diagnostics.Debug.WriteLine(Serialize(generatedMappings));
NhConfiguration.AddDeserializedMapping(generatedMappings, null);
Затем у меня есть тест, который создает схему:
[TestMethod]
public void GenerateSchema()
{
NHibernateConfigurator nhc = new NHibernateConfigurator();
nhc.BuildSessionFactory<MsSql2008Dialect>();
SchemaExport schemaExport = new SchemaExport(nhc.NhConfiguration);
schemaExport.Execute(true, true, false);
}
Когда яСериализация XML, созданного HbmMapping, выглядит следующим образом:
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:nhibernate-mapping-2.2">
<class name="Marathon.MobileApplication.Client.LookupBase, MobileApplication.Client, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="LookupBases" abstract="true">
<id name="Id" type="Int32" />
<discriminator />
<property name="Value" />
<property name="InternalId" />
</class>
<joined-subclass name="ROWMobile.Domain.NotificationMethod, ROWMobile.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" extends="Marathon.MobileApplication.Client.LookupBase, MobileApplication.Client, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
<key column="notificationmethod_key" />
</joined-subclass>
<joined-subclass name="ROWMobile.Domain.ContactMethod, ROWMobile.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" extends="Marathon.MobileApplication.Client.LookupBase, MobileApplication.Client, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
<key column="contactmethod_key" />
</joined-subclass>
<joined-subclass name="ROWMobile.Domain.ContactType, ROWMobile.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" extends="Marathon.MobileApplication.Client.LookupBase, MobileApplication.Client, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
<key column="contacttype_key" />
</joined-subclass>
....
, который создает таблицу LookupBases с таблицей дискриминатора, но также создает таблицу для каждого конкретного класса.Может кто-нибудь сказать, пожалуйста, что я делаю не так?Кроме того, кто-нибудь знает о какой-либо документации, доступной для функции отображения по коду / соглашению, представленной в NHibernate 3.2?