我有一个ProductCategoryModel类:
public class ProductCategoryModel
{
public virtual int id { get; set; }
public virtual string name { get; set; }
public virtual int parentId { get; set; }
public virtual Iesi.Collections.Generic.ISet<ProductCategoryModel> subCategory { get; set; }
}
这是我的映射xml:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Shop.Domain.Model.ProductCategory" assembly="Shop.Domain">
<class name="ProductCategoryModel">
<id name="id" column="id">
<generator class="native" />
</id>
<property name="name" not-null="true" length="50" type="string" column="name"/>
<many-to-one name="parentId" not-null="true" class="ProductCategoryModel" column="parentId"/>
<set name="subCategory" inverse="true">
<key column="parentId"/>
<one-to-many class="ProductCategoryModel"/>
</set>
</class>
</hibernate-mapping>
我的数据库表包含:
id: 2, name: "...", parentId: 0
id: 3, name: "...", parentId: 2
id: 4, name: "...", parentId: 2
现在我要选择ID为2的类别:
session1.Get<ProductCategoryModel>(id);
但是Nhibernate抛出异常:
NHibernate.PropertyAccessException was unhandled
HResult=-2146232832
Message=Invalid Cast (check your mapping for property type mismatches); setter of Shop.Domain.Model.ProductCategory.ProductCategoryModel
Source=NHibernate
StackTrace:
w NHibernate.Tuple.Entity.PocoEntityTuplizer.SetPropertyValuesWithOptimizer(Object entity, Object[] values)
w NHibernate.Tuple.Entity.PocoEntityTuplizer.SetPropertyValues(Object entity, Object[] values)
w NHibernate.Persister.Entity.AbstractEntityPersister.SetPropertyValues(Object obj, Object[] values, EntityMode entityMode)
w NHibernate.Engine.TwoPhaseLoad.InitializeEntity(Object entity, Boolean readOnly, ISessionImplementor session, PreLoadEvent preLoadEvent, PostLoadEvent postLoadEvent)
w NHibernate.Loader.Loader.InitializeEntitiesAndCollections(IList hydratedObjects, Object resultSetId, ISessionImplementor session, Boolean readOnly)
w NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies, IResultTransformer forcedResultTransformer)
w NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies, IResultTransformer forcedResultTransformer)
w NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies)
w NHibernate.Loader.Loader.LoadEntity(ISessionImplementor session, Object id, IType identifierType, Object optionalObject, String optionalEntityName, Object optionalIdentifier, IEntityPersister persister)
w NHibernate.Loader.Entity.AbstractEntityLoader.Load(ISessionImplementor session, Object id, Object optionalObject, Object optionalId)
w NHibernate.Loader.Entity.AbstractEntityLoader.Load(Object id, Object optionalObject, ISessionImplementor session)
w NHibernate.Persister.Entity.AbstractEntityPersister.Load(Object id, Object optionalObject, LockMode lockMode, ISessionImplementor session)
w NHibernate.Event.Default.DefaultLoadEventListener.LoadFromDatasource(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options)
w NHibernate.Event.Default.DefaultLoadEventListener.DoLoad(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options)
w NHibernate.Event.Default.DefaultLoadEventListener.Load(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options)
w NHibernate.Event.Default.DefaultLoadEventListener.ProxyOrLoad(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options)
w NHibernate.Event.Default.DefaultLoadEventListener.OnLoad(LoadEvent event, LoadType loadType)
w NHibernate.Impl.SessionImpl.FireLoad(LoadEvent event, LoadType loadType)
w NHibernate.Impl.SessionImpl.Get(String entityName, Object id)
w NHibernate.Impl.SessionImpl.Get(Type entityClass, Object id)
w NHibernate.Impl.SessionImpl.Get[T](Object id)
w Shop.Infrastructure.Repositories.ProductCategoryIM.GetCategoryById(Int32 id) w f:\Uczelnia\!Semestr VI\Kurs aplikacji bazodanowych\KubutShop2\KubutShop\Shop.Infrastructure\Repositories\ProductCategoryIM.cs:wiersz 58
w Shop.Application.Front.FrontService.GetProductCategoryById(Int32 id) w f:\Uczelnia\!Semestr VI\Kurs aplikacji bazodanowych\KubutShop2\KubutShop\Shop.Application\Front\Front.cs:wiersz 139
w Presentation.ConsoleApp.Program.Main(String[] args) w f:\Uczelnia\!Semestr VI\Kurs aplikacji bazodanowych\KubutShop2\KubutShop\Presentation.ConsoleApp\Program.cs:wiersz 40
w System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
w System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
w Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
w System.Threading.ThreadHelper.ThreadStart_Context(Object state)
w System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
w System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
w System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
w System.Threading.ThreadHelper.ThreadStart()
InnerException: System.InvalidCastException
HResult=-2147467262
Message=Nie można rzutować obiektu typu 'NHibernate.Collection.Generic.PersistentGenericSet`1[Shop.Domain.Model.ProductCategory.ProductCategoryModel]' na typ 'Iesi.Collections.Generic.ISet`1[Shop.Domain.Model.ProductCategory.ProductCategoryModel]'.
Source=Shop.Domain
StackTrace:
w (Object , Object[] , SetterCallback )
w NHibernate.Bytecode.Lightweight.AccessOptimizer.SetPropertyValues(Object target, Object[] values)
w NHibernate.Tuple.Entity.PocoEntityTuplizer.SetPropertyValuesWithOptimizer(Object entity, Object[] values)
InnerException:
消息=Niemożnazutowaćobiektutypu'NHibernate.Collection.Generic.PersistentGenericSet
1[Shop.Domain.Model.ProductCategory.ProductCategoryModel]' na typ Iesi.Collections.Generic.ISet
1 [Shop.Domain.Model.ProductCategory.ProductCategoryModel]'。
意味着这样的事情:
Message =无法强制转换'NHibernate.Collection.Generic.PersistentGenericSet
1[Shop.Domain.Model.ProductCategory.ProductCategoryModel]' to type Iesi.Collections.Generic.ISet
1 [Shop.Domain.Model.ProductCategory.ProductCategoryModel]'
我做错了什么?我读了很多类似的话题,但我仍然不知道哪里出错。 附: 抱歉我的英语很差;)
答案 0 :(得分:0)
使用最新的4.0+ NHibernate版本,我们应该记住这里所描述的真正重要的变化Q & A
让我引用一点(来自release notes):
**已知从NH3.3.3.GA到4.0.0.GA
的突然变化NHibernate现在的目标是.Net 4.0。 Iesi.Collections中集合类型的许多用法现在已更改为使用BCL中的相应类型。这些类型的API略有不同。
所以 - 现在我们即将使用 System
而非 iesi
的内容,例如:
System.Collections.Generic.ISet<T>
第二件事,非常重要的是,我们需要创建双向映射one-to-many
和many-to-one
。这意味着我们不能
// not iesi
// we need System
using System.Collections.Generic;
using System.Collections.ObjectModel;
...
public class ProductCategoryModel
{
...
// could be used just as navigation property
public virtual int parentId { get; set; }
// This is must with inverse="true"
public virtual ProductCategoryModel Parent { get; set; }
// the System.Collections.Generic
public virtual ISet<ProductCategoryModel> SubCategories { get; set; }
...
并映射:
...
// readonly
<property name="parentId" not-null="true" column="parentId" type="string"
insert="false" update="false" />
// inverse end
<many-to-one name="Parent" not-null="true" class="ProductCategoryModel" column="parentId"/>
<set name="SubCategories" inverse="true" batch-size="25">
<key column="parentId"/>
<one-to-many class="ProductCategoryModel"/>
</set>
...
我们可以看到,我们可以为many-to-one
(参考)和property
(valueType or string)
制作映射。其中一个必须是只读(insert =&#34; false&#34; update =&#34; false&#34;)
注意:不要忘记,因为我们使用逆,我们必须在C#中设置关系的两边...