上周我收到了寻找NHibernate hbm映射替代方案的任务,并决定尝试NHibernate映射代码(看到流利的NHibernate项目还没有在最后更新许多年)。感谢NOtherDev blog和其他很多关于SO的问题,我几乎可以映射所有内容,但我仍然有几个问题。
问题:
我有一个实体作为IDocument类型的组件,它有一个这个接口的私有实现,但是当我尝试映射这个组件的各种属性时,我得到错误Could not find property nor field XXX
,因为在界面中这个属性没有设定者。
接口
public interface IDocument : IObject
{
byte[] DocumentData { get; }
string Name { get; }
DocumentFormats Format { get; }
}
实体类(待映射)
public class ArchiveDocument : /* [...] */, IArchiveDocument
{
private readonly MyDocument _document = new MyDocument();
public IDocument Document
{
get { return _document; }
set
{
ThrowExceptionIfReadonly(nameof(Document));
_document.Format = value.Format;
_document.Name = value.Name;
_document.DocumentData = value.DocumentData;
}
}
// private document implementation
private class MyDocument : IDocument
{
public MyDocument(){ /* constructor */}
private byte[] _documentData;
public byte[] DocumentData
{
get { return _documentData; }
set
{
_documentData = value;
}
}
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
private DocumentFormats _format;
public DocumentFormats Format
{
get { return _format; }
set { _format = value; }
}
}
}
映射
public class ArchiveDocumentMap : ClassMapping<ArchiveDocument>
{
Table("DOCUMENT");
Lazy(false);
OptimisticLock(OptimisticLockMode.Version);
Component(d => d.Document, d =>
{
d.Access(Accessor.Field);
d.Property(dd => dd.DocumentData, dd =>
{
dd.Column("DOC_B_DOCUMENT_DATA");
dd.Access(Accessor.Field);
dd.Type<BinaryBlobType>();
dd.Insert(true);
dd.Update(false);
});
d.Property(dd => dd.Format, dd =>
{
dd.Column("DOC_S_FORMAT");
dd.Access(Accessor.Field);
dd.Type<EnumStringType<DocumentFormats>>();
});
d.Property(dd => dd.Name, dd =>
{
dd.Column("DOC_S_NAME");
dd.Access(Accessor.Field);
dd.Type</*own type*/>();
});
});
}
old hbm
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="/*namespace of class*/" assembly="/*namespace of assebly*/.ArchiveDocument">
<class name="ArchiveDocument" table="DOCUMENT" optimistic-lock="version" lazy="false">
<component name="Document" access="field.camelcase-underscore">
<property name="DocumentData" column="DOC_B_DOCUMENT_DATA" access="field.camelcase-underscore" type="BinaryBlob" insert="true" update="false"/>
<property name="Format" column="DOC_S_FORMAT" access="field.camelcase-underscore" type="NHibernate.Type.EnumStringType`1[[/* Enum path */]], NHibernate"/>
<property name="Name" column="DOC_S_NAME" access="field.camelcase-underscore" type="/* Own type (variant of string) */"/>
</component>
</class>
</hibernate-mapping>
错误的
Could not find property nor field 'DocumentData' in class '/* Namespace */.IDocument'
根据我的理解,按代码映射和Fluent NHibernate不是&#34;界面友好&#34;,但在我看来,如果hbm文件能够映射这个类,那么应该映射-码。我做错了什么,或者没有办法按照代码映射做我想做的事情?如果是后者,是否有解决方法?
修改
错误不是DocumentData
特定的,如果我发表评论,Name
和Format
也会发生同样的错误。
编辑2: 完成内部异常的堆栈跟踪
[PropertyNotFoundException: Could not find property nor field 'DocumentData' in class 'Eis.Framework.Business.Core.Document.IDocument']
NHibernate.Properties.FieldAccessor.GetField(Type type, String fieldName, Type originalType) +220
NHibernate.Properties.FieldAccessor.GetField(Type type, String fieldName, Type originalType) +90
NHibernate.Properties.FieldAccessor.GetGetter(Type theClass, String propertyName) +84
NHibernate.Tuple.Component.PocoComponentTuplizer.BuildGetter(Component component, Property prop) +41
NHibernate.Tuple.Component.AbstractComponentTuplizer..ctor(Component component) +168
NHibernate.Tuple.Component.PocoComponentTuplizer..ctor(Component component) +21
NHibernate.Tuple.Component.ComponentEntityModeToTuplizerMapping..ctor(Component component) +368
NHibernate.Tuple.Component.ComponentMetamodel..ctor(Component component) +301
NHibernate.Mapping.Component.BuildType() +28
NHibernate.Mapping.Component.get_Type() +16
NHibernate.Mapping.SimpleValue.IsValid(IMapping mapping) +30
NHibernate.Mapping.PersistentClass.Validate(IMapping mapping) +87
NHibernate.Mapping.RootClass.Validate(IMapping mapping) +35
NHibernate.Cfg.Configuration.ValidateEntities() +169
NHibernate.Cfg.Configuration.Validate() +13
NHibernate.Cfg.Configuration.BuildSessionFactory() +34
[namespace].UnitOfWorkProviderNHibernate.InitializeImpl(IDictionary`2 parameters) in C:\path\to\file\UnitOfWorkProviderNHibernate.cs:241
[namespace].Initialize(IDictionary`2 parameters) in C:\path\to\file\ProviderBase.cs:36
[namespace].InitializeProvider(ProviderItem providerItem) in C:\path\to\file\BusinessProviderFactory.cs:287
编辑3:
我试着看看生成的hbm.xml
文件是什么样的,将它与我们现在使用的文件进行比较,我知道它有效,这是我的发现:
field
而非field.camelcase-underscore
insert=true
中缺少属性DocumentData
(在我的Map类中明确指出)