【问题标题】:How to map Table-Per-Hierarchy with NHibernate 3.2 ConventionModelMapper如何使用 NHibernate 3.2 ConventionModelMapper 映射 Table-Per-Hierarchy
【发布时间】:2011-12-29 16:48:21
【问题描述】:

我正在通过代码/约定使用 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);
}

当我对生成的 HbmMapping 进行 Xml 序列化时,它看起来像这样:

<?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 中引入的按代码/约定功能映射的可用文档?

【问题讨论】:

    标签: nhibernate nhibernate-mapping


    【解决方案1】:

    您是否考虑过为似乎无法正常工作的部分添加 hbm?我知道这是一个 hack,但它似乎对我有用。

    【讨论】:

    • 感谢您的建议。我实际上通过切换到 Fluent NHibernate 解决了这个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-08
    • 1970-01-01
    • 2015-12-04
    • 1970-01-01
    • 1970-01-01
    • 2013-05-09
    • 1970-01-01
    相关资源
    最近更新 更多