我正在尝试使用NHibernate来映射使用decimal(9,0)
(~32位整数)“版本属性”的遗留数据库(用于每行的乐观锁定)。
这些字段在数据库中声明为可空,并在NHibernate参考手册的5.1.7节中声明:
版本号可以是Int64,Int32,Int16,Ticks,Timestamp或TimeSpan(或者它们可以为空的对应物)类型 在.NET 2.0中。)
...所以我将它们映射为int?
版本属性。
我的地图文档与此类似:
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping namespace="Model" assembly="Model" xmlns="urn:nhibernate-mapping-2.2">
<class name="Bar" lazy="true" table="`BAR`" schema="`dbo`">
<id name="ID" access="property" column="`ID`">
<generator class="assigned" />
</id>
<version name="Version" column="`VERSION`" type="int?" />
<!-- ... etc ... -->
</class>
</hibernate-mapping>
然而,在运行时,这种情况失败了,例外情况类似于:
failed: NHibernate.MappingException : Could not compile the mapping document: Model.Mappings.Bar.hbm.xml
----> NHibernate.MappingException : Could not determine type for: Model.int?, for columns: NHibernate.Mapping.Column(VERSION)
at NHibernate.Cfg.Configuration.LogAndThrow(Exception exception)
at NHibernate.Cfg.Configuration.AddValidatedDocument(NamedXmlDocument doc)
at NHibernate.Cfg.Configuration.ProcessMappingsQueue()
at NHibernate.Cfg.Configuration.AddDocumentThroughQueue(NamedXmlDocument document)
at NHibernate.Cfg.Configuration.AddXmlReader(XmlReader hbmReader, String name)
at NHibernate.Cfg.Configuration.AddInputStream(Stream xmlInputStream, String name)
at NHibernate.Cfg.Configuration.AddResource(String path, Assembly assembly)
at NHibernate.Cfg.Configuration.AddAssembly(Assembly assembly)
Core\DAOUtils.cs(33,0): at Core.DAOUtils.OpenSession()
test\cs\FooTest.cs(65,0): at DataModel.Tests.FooTest.TestSelectStar()
--MappingException
at NHibernate.Mapping.SimpleValue.get_Type()
at NHibernate.Cfg.XmlHbmBinding.RootClassBinder.BindProperty(HbmVersion versionSchema, Property property, IDictionary`2 inheritedMetas)
at NHibernate.Cfg.XmlHbmBinding.RootClassBinder.BindVersion(HbmVersion versionSchema, PersistentClass rootClass, Table table, IDictionary`2 inheritedMetas)
at NHibernate.Cfg.XmlHbmBinding.RootClassBinder.Bind(XmlNode node, HbmClass classSchema, IDictionary`2 inheritedMetas)
at NHibernate.Cfg.XmlHbmBinding.MappingRootBinder.AddRootClasses(XmlNode parentNode, IDictionary`2 inheritedMetas)
at NHibernate.Cfg.XmlHbmBinding.MappingRootBinder.Bind(XmlNode node)
at NHibernate.Cfg.Configuration.AddValidatedDocument(NamedXmlDocument doc)
是否有一些技巧可以正确使用NHibernate的版本属性,或者我做错了什么?
对我来说奇怪的是,NHibernate似乎将我的程序集/命名空间名称附加到int?
类型的开头,这似乎是错误的。
修改
将映射文件更改为使用int
而不是int?
后,我现在遇到以下异常:
System.InvalidCastException : Unable to cast object of type 'NHibernate.Type.DecimalType' to type 'NHibernate.Type.IVersionType'.
at NHibernate.Tuple.PropertyFactory.BuildVersionProperty(Property property, Boolean lazyAvailable)
at NHibernate.Tuple.Entity.EntityMetamodel..ctor(PersistentClass persistentClass, ISessionFactoryImplementor sessionFactory)
at NHibernate.Persister.Entity.AbstractEntityPersister..ctor(PersistentClass persistentClass, ICacheConcurrencyStrategy cache, ISessionFactoryImplementor factory)
at NHibernate.Persister.Entity.SingleTableEntityPersister..ctor(PersistentClass persistentClass, ICacheConcurrencyStrategy cache, ISessionFactoryImplementor factory, IMapping mapping)
at NHibernate.Persister.PersisterFactory.CreateClassPersister(PersistentClass model, ICacheConcurrencyStrategy cache, ISessionFactoryImplementor factory, IMapping cfg)
at NHibernate.Impl.SessionFactoryImpl..ctor(Configuration cfg, IMapping mapping, Settings settings, EventListeners listeners)
at NHibernate.Cfg.Configuration.BuildSessionFactory()
不幸的是,NHibernate在这里没有给我一个非常详细的错误信息(很高兴知道数百个类中的哪个类正在抛出这个),而且我无法说服log4net工作,所以我暂时不知所措。
编辑#2:
总结“技巧”:
decimal
),请确保在映射XML中将所有版本属性声明为int
。 (虽然如果在POCO中宣布int?
,它应该有效)decimal
类型(在POCO或映射XML中)答案 0 :(得分:1)
你不应该包括'?'在映射中 - 而不是写入类型=“Int32”。如果您的POCO中的财产可以为空,那么它应该可以正常运作。 (至少它适用于属性 - 我没有尝试过可以使用可以为空的版本列...)。