Nhibernate 无法扩展未映射的类:实体

Nhibernate 无法扩展未映射的类:实体,nhibernate,nhibernate-mapping,Nhibernate,Nhibernate Mapping,我有一个名为Entity的基类: public class Entity { public int Id {get;set;} } 假设我有一个名为Customer的类: public class Customer : Entity { public string Name {get;set;} } 现在,使用NHibernate 3.3.1中基于约定的代码映射,我尝试以下操作: public static class DataHelper { private sta

我有一个名为Entity的基类:

public class Entity
{
    public int Id {get;set;}
}
假设我有一个名为Customer的类:

public class Customer : Entity
{
    public string Name {get;set;}
}
现在,使用NHibernate 3.3.1中基于约定的代码映射,我尝试以下操作:

public static class DataHelper
{
    private static HbmMapping GetMappings()
    {
        var mapper = new CustomModelMapper(typeof(Entity));           

        return mapper.CompileMappingFor(
            typeof(DataHelper).Assembly.GetExportedTypes()
                .Where(x => x.IsSubclassOf(typeof(Entity))));
    }
}
当我尝试运行我的应用程序时,出现错误“无法扩展未映射的类:实体”。我不想映射实体类——它只是继承一些公共属性的基类。如何让NHibernate忽略未映射的类?下面列出了我的CustomModelMapper类以供参考

下面列出了CustomModelMapper类的代码以供参考

internal class CustomModelMapper : ConventionModelMapper
{
    private const int DEFAULT_STRING_LENGTH = 100;
    private Type baseType;

    public CustomModelMapper(Type baseType)
    {
        this.baseType = baseType;
    }

    public CustomModelMapper()
    {
        SetupInspectors();
    }

    protected override void AppendDefaultEvents()
    {
        base.AppendDefaultEvents();
        BeforeMapClass += OnBeforeMapClass;
        BeforeMapProperty += OnBeforeMapProperty;
        BeforeMapManyToOne += OnBeforeMapManyToOne;
        BeforeMapBag += OnBeforeMapBag;
        BeforeMapList += OnBeforeMapList;
        BeforeMapSet += OnBeforeMapSet;
    }

    protected void OnBeforeMapClass(IModelInspector modelInspector, Type type, IClassAttributesMapper classCustomizer)
    {
        classCustomizer.Id(type.GetProperty("Id"), m => m.Generator(Generators.Native));
    }

    protected void OnBeforeMapProperty(IModelInspector modelInspector, PropertyPath member, IPropertyMapper propertyCustomizer)
    {
        if (member.LocalMember.GetPropertyOrFieldType().IsEnum)
        {
            var type = member.LocalMember.GetPropertyOrFieldType();
            var genericType = typeof(EnumStringType<>).MakeGenericType(type);
            propertyCustomizer.Type(genericType, null);
        }

        if (member.LocalMember.GetPropertyOrFieldType() == typeof(string))
            propertyCustomizer.Length(DEFAULT_STRING_LENGTH);
    }

    protected void OnBeforeMapManyToOne(IModelInspector modelInspector, PropertyPath member, IManyToOneMapper propertyCustomizer)
    {
        propertyCustomizer.Cascade(Cascade.All);
        propertyCustomizer.Fetch(FetchKind.Join);
        propertyCustomizer.Lazy(LazyRelation.NoLazy);

        propertyCustomizer.Index(string.Format("IX{0}{1}",
            member.GetContainerEntity(modelInspector).Name,
            member.LocalMember.Name));
    }

    protected void OnBeforeMapBag(IModelInspector modelInspector, PropertyPath member, IBagPropertiesMapper propertyCustomizer)
    {
        propertyCustomizer.Cascade(Cascade.All);
        propertyCustomizer.Lazy(CollectionLazy.Extra);
        propertyCustomizer.Fetch(CollectionFetchMode.Subselect);
    }

    protected void OnBeforeMapList(IModelInspector modelInspector, PropertyPath member, IListPropertiesMapper propertyCustomizer)
    {
        propertyCustomizer.Cascade(Cascade.All);
        propertyCustomizer.Lazy(CollectionLazy.Extra);
        propertyCustomizer.Fetch(CollectionFetchMode.Subselect);
    }

    protected void OnBeforeMapSet(IModelInspector modelInspector, PropertyPath member, ISetPropertiesMapper propertyCustomizer)
    {
        propertyCustomizer.Cascade(Cascade.All);
        propertyCustomizer.Lazy(CollectionLazy.Extra);
        propertyCustomizer.Fetch(CollectionFetchMode.Subselect);
    }

    protected void SetupInspectors()
    {
        IsRootEntity((type, declared) =>
        {
            return baseType.Equals(type.BaseType);
        });

        IsEntity((type, declared) =>
        {
            return baseType.IsAssignableFrom(type) && !type.IsInterface;
        });

        IsVersion((member, declared) =>
        {
            return
                member.Name == "Version" &&
                member.MemberType == MemberTypes.Property &&
                member.GetPropertyOrFieldType() == typeof(int);
        });


        IsBag((member, declared) =>
        {
            if (member.GetPropertyOrFieldType().IsGenericType)
                return IsGenericType(member, typeof(ICollection<>));

            return false;
        });

        IsList((member, declared) =>
        {
            if (member.GetPropertyOrFieldType().IsGenericType)
                return IsGenericType(member, typeof(IList<>));

            return false;
        });

        IsSet((member, declared) =>
        {
            if (member.GetPropertyOrFieldType().IsGenericType)
                return IsGenericType(member, typeof(ICG.ISet<>));

            return false;
        });
    }

    protected static bool IsGenericType(MemberInfo member, Type targetType)
    {
        var type = member.GetPropertyOrFieldType();
        var generics = type.GetGenericInterfaceTypeDefinitions();
        return generics.Contains(targetType);
    }
}
内部类CustomModelMapper:ConventionModelMapper
{
private const int DEFAULT_STRING_LENGTH=100;
私有类型baseType;
公共CustomModelMapper(类型baseType)
{
this.baseType=baseType;
}
公共CustomModelMapper()
{
设置检查员();
}
受保护的覆盖无效AppendDefaultEvents()
{
base.AppendDefaultEvents();
BeforeMapClass+=OnBeforeMapClass;
BeforeMapProperty+=OnBeforeMapProperty;
BeforeMapManyTone+=OnBeforeMapManyTone;
beforemappag+=onbeforemappag;
BeforeMapList+=OnBeforeMapList;
BeforeMapSet+=OnBeforeMapSet;
}
BeforeMapClass上受保护的void(IModeInspector modelInspector,类型类型,IClassAttributesMapper classCustomizer)
{
Id(type.GetProperty(“Id”),m=>m.Generator(Generators.Native));
}
BeforeMapproperty上受保护的void(IModeInspector modelInspector、PropertyPath成员、IPropertyMapper propertyCustomizer)
{
if(member.LocalMember.GetPropertyOrFieldType().IsEnum)
{
var type=member.LocalMember.GetPropertyOrFieldType();
var genericType=typeof(EnumStringType)。MakeGenericType(type);
propertyCustomizer.Type(genericType,null);
}
if(member.LocalMember.GetPropertyOrFieldType()==typeof(string))
propertyCustomizer.Length(默认字符串长度);
}
BeforeMapManyToOne上的受保护无效(IModeInspector modelInspector、PropertyPath成员、IManyToOneMapper propertyCustomizer)
{
propertyCustomizer.Cascade(Cascade.All);
propertyCustomizer.Fetch(FetchKind.Join);
propertyCustomizer.Lazy(LazyRelation.NoLazy);
propertyCustomizer.Index(string.Format(“IX{0}{1}”),
member.GetContainerEntity(modelInspector).Name,
member.LocalMember.Name));
}
BeforeMapBag上的受保护无效(IModeInspector modelInspector、PropertyPath成员、IBagPropertiesMapper propertyCustomizer)
{
propertyCustomizer.Cascade(Cascade.All);
propertyCustomizer.Lazy(CollectionLazy.Extra);
propertyCustomizer.Fetch(CollectionFetchMode.Subselect);
}
BeforeMapList上受保护的void(IModeInspector modelInspector、PropertyPath成员、IListProperties映射器propertyCustomizer)
{
propertyCustomizer.Cascade(Cascade.All);
propertyCustomizer.Lazy(CollectionLazy.Extra);
propertyCustomizer.Fetch(CollectionFetchMode.Subselect);
}
BeforeMapset(IModeInspector modelInspector、PropertyPath成员、ISetPropertiesMapper propertyCustomizer)上受保护的void
{
propertyCustomizer.Cascade(Cascade.All);
propertyCustomizer.Lazy(CollectionLazy.Extra);
propertyCustomizer.Fetch(CollectionFetchMode.Subselect);
}
受保护的无效设置检查器()
{
IsRootEntity((类型,声明)=>
{
返回baseType.Equals(type.baseType);
});
IsEntity((类型,声明)=>
{
返回baseType.IsAssignableFrom(type)&&!type.IsInterface;
});
IsVersion((成员,声明)=>
{
返回
member.Name==“版本”&&
member.MemberType==MemberTypes.Property&&
member.GetPropertyOrFieldType()==typeof(int);
});
IsBag((成员,声明)=>
{
if(member.GetPropertyOrFieldType().IsGenericType)
返回IsGenericType(成员,typeof(ICollection));
返回false;
});
IsList((成员,已声明)=>
{
if(member.GetPropertyOrFieldType().IsGenericType)
返回IsGenericType(成员,typeof(IList));
返回false;
});
IsSet((成员,声明)=>
{
if(member.GetPropertyOrFieldType().IsGenericType)
返回IsGenericType(成员,typeof(ICG.ISet));
返回false;
});
}
受保护的静态bool IsGenericType(MemberInfo成员,类型targetType)
{
var type=member.GetPropertyOrFieldType();
var generics=type.GetGenericInterfaceTypeDefinitions();
返回泛型.Contains(targetType);
}
}

问题可能出在您的
实体上。当前,对于
实体
类本身,它将返回true。只需再加一张支票:

IsEntity((type, declared) =>
{
    return baseType.IsAssignableFrom(type) && !type.IsInterface &&
           type != typeof(Entity); // <- skip Entity class
});
IsEntity((类型,声明)=>
{
返回baseType.IsAssignableFrom(type)&&!type.IsInterface&&

type!=typeof(Entity);//不,我试过了,但仍然得到了相同的结果。对于通过GetExportedTypes()调用收集的实体,似乎抛出了错误,这些实体没有通过
mapper.Class()显式声明
调用。这些调用在映射文档中显示为JoinedSubclass。如果我添加一个空的映射语句,例如
mapper.Class(map=>{})
对于每个类,错误都会消失,并且每个类在映射文档中都列为根类。因此,我想问题是,如何确保NHibernate将所有实体类都视为根类?