首页 \ 问答 \ 无法扩展未映射的类:实体(Cannot extend unmapped class: Entity)

无法扩展未映射的类:实体(Cannot extend unmapped class: Entity)

我有一个名为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))));
    }
}

当我尝试运行我的应用程序时,我收到错误“无法扩展未映射的类:实体”。 我不想映射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);
    }
}

I have a base class called Entity:

public class Entity
{
    public int Id {get;set;}
}

Let's say I have a class called Customer:

public class Customer : Entity
{
    public string Name {get;set;}
}

Now, using convention based mapping by code in NHibernate 3.3.1, I try the following:

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))));
    }
}

When I try to run my app, I get the error "Cannot extend unmapped class: Entity". I don't want to map the Entity class - it's just a base class for inheriting some common properties. How can I tell NHibernate to ignore the unmapped class? For reference, my CustomModelMapper class is listed below.

The code for my CustomModelMapper class is listed below for reference

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);
    }
}

原文:https://stackoverflow.com/questions/11402502
更新时间:2022-11-02 09:11

最满意答案

在查看Sencha Touch代码时,我认为您必须向面板的eventedConfig属性添加material ,因为set touch/src/Evented.js的setter设置如下:

for (name in eventedConfig) {
    if (eventedConfig.hasOwnProperty(name)) {
        nameMap = ExtClass.getConfigNameMap(name);
        data[nameMap.set] = this.generateSetter(nameMap);
    }
}

你无法影响eventedConfig属性,你必须为此定义一个覆盖,这将影响所有面板:

Ext.define('MyApp.override.Panel',{
    override: 'Ext.panel.Panel',
    constructor:function() {
        this.callParent(arguments);
        this.eventedConfig.material = "SomeDefaultValue";
    }
});

或者定义派生类并使用它:

Ext.define('MyApp.ux.Panel',{
    extend: 'Ext.panel.Panel',
    xtype: 'mypanel',
    constructor:function() {
        this.callParent(arguments);
        this.eventedConfig.material = "SomeDefaultValue";
    }
});

When looking into the Sencha Touch code, I think you would have to add material to the panel's eventedConfig property, because the setters are set as follows in touch/src/Evented.js:

for (name in eventedConfig) {
    if (eventedConfig.hasOwnProperty(name)) {
        nameMap = ExtClass.getConfigNameMap(name);
        data[nameMap.set] = this.generateSetter(nameMap);
    }
}

You can't influence the eventedConfig property inside Ext.create, you would have to define an override for this, which would influence all panels:

Ext.define('MyApp.override.Panel',{
    override: 'Ext.panel.Panel',
    constructor:function() {
        this.callParent(arguments);
        this.eventedConfig.material = "SomeDefaultValue";
    }
});

or define a derived class and use that:

Ext.define('MyApp.ux.Panel',{
    extend: 'Ext.panel.Panel',
    xtype: 'mypanel',
    constructor:function() {
        this.callParent(arguments);
        this.eventedConfig.material = "SomeDefaultValue";
    }
});

相关问答

更多
  • 来自Sencha论坛 : 目前,Sencha Touch支持Webkit浏览器,更具体地说,支持iOS 3+和Android 2.0+(请注意,不支持Android 2.0以下,因此不支持运行较旧设备的Android 1.6)。 From Sencha Forum: Currently, Sencha Touch supports Webkit browsers, more specifically, iOS 3+ and Android 2.0+ (note that below Android 2.0 ...
  • Sencha touch对于那些用于网页设计的用户而言更为复杂,因为它几乎是一个纯粹的编程模型(您不用html设计页面,以编程方式向页面添加元素)。 然而,它有一个更丰富的小部件模型,并且比jQTouch更丰富(它也是更大)... JQTouch更容易在飞行中运行(您基本上是在单个页面上设计div的页面),但是,如果您打算拥有很多屏幕,则必须非常明智地将应用程序分解成多个页面或创建您的页面动态地在Javascript中(至少在很多版本的Android和iPhone 3G上)DOM操纵与很多页面往往是缓慢发生 ...
  • 主要区别在于PhoneGap是一个不包含内置UI框架的框架。 相反,它只是作为本机API的跨平台包装器,向您展示基于Javascript的API以访问本机功能。 使用PhoneGap,您可以选择使用纯HTML5,或使用UI框架,如Sencha Touch 2本身,jQueryMobile,jQTouch,Kendo UI等。另一方面,Sencha Touch是一个UI框架,但它没有开箱即用的功能,可以为本机功能公开跨平台JavaScript API。 从您的以下声明中,我认为您不打算访问应用程序中的任何本机 ...
  • 为了实现这一点,您可以使用Ext.Menu并将其安装在左侧或右侧。 对于此功能,您不需要第三方库,它已包含在Sencha Touch中。 http://docs.sencha.com/touch/2.3.0/#!/api/Ext.Menu In order to achieve this you can use Ext.Menu and mount it on the left or right side. You don't need third party library for this featur ...
  • 最适合您的选择是TouchTreeGrid: https : //github.com/swluken/TouchTreeGrid The best option for you will be TouchTreeGrid: https://github.com/swluken/TouchTreeGrid
  • Sencha Touch是Javascript。 它是用JS编写的,图书馆里没有什么魔力。 如果你了解JS,你应该能够理解Sencha Touch。 Sencha Touch和JQuery是解决相同问题的非常不同的方法。 Sencha Touch使用面向对象的编程概念远远超过jQuery。 同样,有些东西非常相似。 在jQuery中工作了很长时间后,在接近其他Javascript库时需要有一个开放的头脑,因为jQuery没有遵循不同的概念。 图书馆也针对不同的“利基”。 我会说Sencha Touch更像是 ...
  • 在查看Sencha Touch代码时,我认为您必须向面板的eventedConfig属性添加material ,因为set touch/src/Evented.js的setter设置如下: for (name in eventedConfig) { if (eventedConfig.hasOwnProperty(name)) { nameMap = ExtClass.getConfigNameMap(name); data[nameMap.set] = this.g ...
  • 非常相似,是的。 这两个框架处理建议的体系结构(MVC)的方式对我来说最大的区别。 ExtJS 4还没有Ext.Dispatch,这意味着你的控制器逻辑变得更倾向于听事件。 另一方面,触摸MVC可以使用Ext.Dispatch进行程序流程,这让我更喜欢。 不过,我想这是个人偏好。 关于你的第二个问题,你是否应该首先学习ExtJS,我会说这完全取决于你想要做什么。 学习一个人非常了解另一个人。 如果您感兴趣的是移动设备,听起来像是什么,那么请直接联系Touch。 有一些精彩的Touch教程,fx: http ...
  • getRandomInt() 是包含math.random的本地函数。 你应该创建该功能。 getRandomInt() Is a local function which contains the math.random. You should create that function.
  • 看看https://github.com/mitchellsimoens/Ext.ux.touch.grid这是Sencha Touch的网格实现。 have a look at https://github.com/mitchellsimoens/Ext.ux.touch.grid This is a grid implementation for Sencha Touch.

相关文章

更多

最新问答

更多
  • sp_updatestats是否导致SQL Server 2005中无法访问表?(Does sp_updatestats cause tables to be inaccessible in SQL Server 2005?)
  • 如何创建一个可以与持续运行的服务交互的CLI,类似于MySQL的shell?(How to create a CLI that can interact with a continuously running service, similar to MySQL's shell?)
  • AESGCM解密失败的MAC(AESGCM decryption failing with MAC)
  • Zurb Foundation 4 - 嵌套网格对齐问题(Zurb Foundation 4 - Nested grid alignment issues)
  • 湖北京山哪里有修平板计算机的
  • SimplePie问题(SimplePie Problem)
  • 在不同的任务中,我们可以同时使用多少“上下文”?(How many 'context' we can use at a time simultaneously in different tasks?)
  • HTML / Javascript:从子目录启用文件夹访问(HTML/Javascript: Enabling folder access from a subdirectory)
  • 为什么我会收到链接错误?(Why do I get a linker error?)
  • 如何正确定义析构函数(How to properly define destructor)
  • 垂直切换菜单打开第3级父级。(Vertical toggle menu 3rd level parent stay opened. jQuery)
  • 类型不匹配 - JavaScript(Type mismatch - JavaScript)
  • 为什么当我将模型传递给我的.Net MVC 4控制器操作时,它坚持在部分更新中使用它?(Why is it that when I pass a Model to my .Net MVC 4 Controller Action it insists on using it in the Partial Update?)
  • 在使用熊猫和statsmodels时拉取变量名称(Pulling variable names when using pandas and statsmodels)
  • 如何开启mysql计划事件
  • 检查数组的总和是否大于最大数,反之亦然javascript(checking if sum of array is greater than max number and vice versa javascript)
  • 使用OpenGL ES绘制轮廓(Drawing Outline with OpenGL ES)
  • java日历格式(java Calendar format)
  • Python PANDAS:将pandas / numpy转换为dask数据框/数组(Python PANDAS: Converting from pandas/numpy to dask dataframe/array)
  • 如何搜索附加在elasticsearch索引中的文档的内容(How to search a content of a document attached in elasticsearch index)
  • LinQ to Entities:做相反的查询(LinQ to Entities: Doing the opposite query)
  • 从ExtJs 4.1商店中删除记录时会触发哪些事件(Which events get fired when a record is removed from ExtJs 4.1 store)
  • 运行javascript后如何截取网页截图[关闭](How to take screenshot of a webpage after running javascript [closed])
  • 如何使用GlassFish打印完整的堆栈跟踪?(How can I print the full stack trace with GlassFish?)
  • 如何获取某个exe应用程序的出站HTTP请求?(how to get the outbound HTTP request of a certain exe application?)
  • 嗨,Android重叠背景片段和膨胀异常(Hi, Android overlapping background fragment and inflate exception)
  • Assimp详细说明typedef(Assimp elaborated type refers to typedef)
  • 初始化继承类中不同对象的列表(initialize list of different objects in inherited class)
  • 使用jquery ajax在gridview行中保存星级评分(Save star rating in a gridview row using jquery ajax)
  • Geoxml3 groundOverlay zIndex(Geoxml3 groundOverlay zIndex)