接口类型的Nhibernate映射类组件

时间:2017-11-27 08:40:08

标签: c# nhibernate mapping-by-code

上周我收到了寻找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特定的,如果我发表评论,NameFormat也会发生同样的错误。

编辑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文件是什么样的,将它与我们现在使用的文件进行比较,我知道它有效,这是我的发现:

  • 在组件标记中填充了class属性(即使我没有在我的Map类中指定它)
  • 访问者为field而非field.camelcase-underscore
  • insert=true中缺少属性DocumentData(在我的Map类中明确指出)

            

0 个答案:

没有答案