无法扩展未映射的类:实体(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
最满意答案
在查看Sencha Touch代码时,我认为您必须向面板的
eventedConfig
属性添加material
,因为settouch/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'seventedConfig
property, because the setters are set as follows intouch/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 Vs JQTouch(Sencha Touch Vs JQTouch)[2023-08-04]
Sencha touch对于那些用于网页设计的用户而言更为复杂,因为它几乎是一个纯粹的编程模型(您不用html设计页面,以编程方式向页面添加元素)。 然而,它有一个更丰富的小部件模型,并且比jQTouch更丰富(它也是更大)... JQTouch更容易在飞行中运行(您基本上是在单个页面上设计div的页面),但是,如果您打算拥有很多屏幕,则必须非常明智地将应用程序分解成多个页面或创建您的页面动态地在Javascript中(至少在很多版本的Android和iPhone 3G上)DOM操纵与很多页面往往是缓慢发生 ... -
Sencha Touch 2 Vs.(Sencha Touch 2 Vs. Phonegap)[2024-01-24]
主要区别在于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 ...
-
Sencha Touch 2 Grid(Sencha Touch 2 Grid)[2023-02-09]
最适合您的选择是TouchTreeGrid: https : //github.com/swluken/TouchTreeGrid The best option for you will be TouchTreeGrid: https://github.com/swluken/TouchTreeGrid -
了解Sencha Touch语法(Understand Sencha Touch syntax)[2022-08-16]
Sencha Touch是Javascript。 它是用JS编写的,图书馆里没有什么魔力。 如果你了解JS,你应该能够理解Sencha Touch。 Sencha Touch和JQuery是解决相同问题的非常不同的方法。 Sencha Touch使用面向对象的编程概念远远超过jQuery。 同样,有些东西非常相似。 在jQuery中工作了很长时间后,在接近其他Javascript库时需要有一个开放的头脑,因为jQuery没有遵循不同的概念。 图书馆也针对不同的“利基”。 我会说Sencha Touch更像是 ... -
覆盖Sencha Touch类(Override Sencha Touch class)[2023-09-09]
在查看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.