Как отобразить таблицу на иерархию с помощью NHibernate 3.2 ConventionModelMapper - PullRequest
3 голосов
/ 15 ноября 2011

Я использую отображение 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?

1 Ответ

0 голосов
/ 29 декабря 2011

Рассматривали ли вы добавление hbm для частей, которые, кажется, не работают правильно?Я знаю, что это хак, но мне кажется, что это работает.

...