如何使用NHibernate 3.2 ConventionModelMapper映射Table-Per-Hierarchy

时间:2011-11-15 16:36:40

标签: nhibernate nhibernate-mapping

我正在使用NHibernate 3.2按代码/约定进行映射,并且无法映射简单的table-per-hierachy继承。我的基类是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 :(得分:0)

你有没有考虑为那些似乎没有正常工作的部分添加hbm?我知道这是一个黑客,但似乎对我有用。