无法使用 xml 映射的连接子类来扩展使用 NHibernate.Mapping.ByCode 构建的映射

Can not use joined-subclass of xml mapping to extend the mappings build with NHibernate.Mapping.ByCode

我正在重构 NHibernate.AspNetCore.Identity to NHibernate.Mapping.ByCode , as descripted in the issue https://github.com/nhibernate/NHibernate.AspNetCore.Identity/issues/16 的映射。

我已经用 ClassMapping<T> 重写了 NHibernate.AspNetCore.Identity 的原始 xml 映射,代码如下所示:

public class IdentityRoleMappingPostgreSql : ClassMapping<IdentityRole> {

    public IdentityRoleMappingPostgreSql() {
        Schema("public");
        Table("aspnet_roles");
        Id(e => e.Id, id => {
            id.Column("id");
            id.Type(NHibernateUtil.String);
            id.Length(32);
            id.Generator(Generators.TriggerIdentity);
        });
        Property(e => e.Name, prop => {
            prop.Column("name");
            prop.Type(NHibernateUtil.String);
            prop.Length(64);
            prop.NotNullable(true);
            prop.Unique(true);
        });
        /* other property mappings ignored here .*/
    }

}

完整的映射代码在这里:

https://github.com/nhibernate/NHibernate.AspNetCore.Identity/tree/master/src/NHibernate.AspNetCore.Identity/Entities

然后我尝试使用 joined-sublcass 或 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"
  namespace="WebTest.Entities" assembly="WebTest">

  <joined-subclass name="AppRole" schema="public" table="app_roles" extends="NHibernate.AspNetCore.Identity.IdentityRole, NHibernate.AspNetCore.Identity, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
    <key column="id" />
    <property name="Description" column="description" type="string" length="256" />
  </joined-subclass>

</hibernate-mapping>

我在设置 nhibernate 时遇到以下异常:

NHibernate.MappingException : These classes referenced by 'extends' were not found:
FullName:NHibernate.AspNetCore.Identity.IdentityRole - Name:NHibernate.AspNetCore.Identity.IdentityRole, NHibernate.AspNetCore.Identity, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
FullName:NHibernate.AspNetCore.Identity.IdentityUser - Name:NHibernate.AspNetCore.Identity.IdentityUser, NHibernate.AspNetCore.Identity, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
   at NHibernate.Cfg.MappingsQueue.CheckNoUnavailableEntries()
   at NHibernate.Cfg.Configuration.SecondPassCompile()
   at NHibernate.Cfg.Configuration.BuildMappings()
   at UnitTest.IdentityTest._02_CanSetupMappingByXml()

然后我用 JoinedSubclassMapping<AppRole> 重写 xml 映射,这有效,可以毫无例外地建立会话工厂和查询。

public class AppRoleMapping : JoinedSubclassMapping<AppRole> {

    public AppRoleMapping() {
        ExplicitDeclarationsHolder
            .AddAsRootEntity(typeof(NHIdentityRole));
        Extends(typeof(NHIdentityRole));
        Schema("public");
        Table("app_roles");
        Key(k => k.Column("id"));
        Property(
            p => p.Description,
            maping => {
                maping.Column("description");
                maping.Type(NHibernateUtil.String);
                maping.Length(256);
            }
        );
    }

}

所以问题是:

完整的测试代码在这里:https://github.com/nhibernate/NHibernate.AspNetCore.Identity/blob/master/test/UnitTest/IdentityTest.cs

也许我做错了什么,或者 nhibernate 的映射有问题?

调试并检查 NHibernate.Cfg.Configuration 的源代码后,有一个内部验证队列来处理 xml 添加的映射,但现在可以跳过它,所以简单的解决方法是将 HbmMapping 转换为 xml,然后将 xml 添加到配置中,让我们仔细检查一下。

var mapper = new ModelMapper();
mapper.AddMapping<IdentityRoleMappingPostgreSql>();
// add other mapping here.
var mapping = mapper.CompileMappingForAllExplicitlyAddedEntities();
// Use AddXml instead of AddMappings
cfg.AddXml(mapping.AsString());