NHibernate.MappingException:NHibernate.PropertyNotFoundException:在类中找不到属性的获取器

时间:2019-06-27 07:19:08

标签: c# .net nhibernate nhibernate-mapping

nHibernate将枚举映射到数据库时遇到麻烦。

试图查看映射,但看不到任何错误,至此我怀疑是它可能与枚举有关?

这里是Fortron.Crm.Domain.Policy:

namespace Fortron.Crm.Domain
{
   [Serializable]
   public class Policy
   {
      private PolicyStatus _policyStatus;

      public PolicyStatus PolicyStatus
      {
          get { return _policyStatus; }
          set { _policyStatus = value; }
      }
   }

这是类映射

  <class name="Fortron.Crm.Domain.Policy, Fortron.Crm.Domain" table="Policy" lazy="false">
    <id name="Id" access="nosetter.camelcase-underscore" column="PolicyId" unsaved-value="-1">
      <generator class="identity" />
    </id>
    <set name="Claims" access="field.camelcase-underscore" inverse="true" lazy="false" cascade="save-update">
      <key column="PolicyId" />
      <one-to-many class="Fortron.Crm.Domain.Claim, Fortron.Crm.Domain" />
    </set>
    <many-to-one name="Product" column="ProductId" access="nosetter.camelcase-underscore" />
    <property name="PolicyNumber" />
    <property name="VehicleRegistrationNumber" />
    <property name="ContractNumber" />
    <property name="ContractPaymentAuthorised" />
    <property name="ContractPaymentAuthorisedAt" />
    <component name="Contact" access="nosetter.camelcase-underscore">
      <property name="Title" />
      <property name="GivenNames" />
      <property name="Surname" />
      <property name="BusinessName" />
      <property name="DateOfBirth" />
      <property name="Gender" column="GenderId" />
      <property name="TelephoneNumber" />
      <property name="MobileTelephoneNumber" />
      <property name="WorkTelephoneNumber" />
      <component name="Address" access="nosetter.camelcase-underscore">
        <property name="StreetLine1" column="StreetLine1" />
        <property name="StreetLine2" column="StreetLine2" />
        <property name="CityTown" column="CityTown" />
        <property name="Postcode" column="Postcode" />
        <many-to-one name="StateTerritory" column="StateTerritoryId" />
      </component>
    </component>
    <property name="CustomerNumber" column="CustomerNumber" not-null="false" />
    <property name="Vin" column="Vin" not-null="false"  />
    <property name="PolicyStatus" column="PolicyStatusId" />
  </class>

最后是堆栈跟踪:

Service cannot be started. System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> NHibernate.MappingException: Could not compile the mapping document: Fortron.Crm.Domain.Policy.hbm.xml ---> NHibernate.MappingException: Problem trying to set property type by reflection ---> NHibernate.MappingException: class Fortron.Crm.Domain.Policy, Fortron.Crm.Domain, Version=2.0.0.1, Culture=neutral, PublicKeyToken=6f168f2566a816b4 not found while looking for property: PolicyStatus ---> NHibernate.PropertyNotFoundException: Could not find a getter for property 'PolicyStatus' in class 'Fortron.Crm.Domain.Policy'
   at NHibernate.Properties.BasicPropertyAccessor.GetGetter(Type type, String propertyName)
   at NHibernate.Util.ReflectHelper.ReflectedPropertyClass(String className, String name, String accessorName)
   --- End of inner exception stack trace ---
   at NHibernate.Util.ReflectHelper.ReflectedPropertyClass(String className, String name, String accessorName)
   at NHibernate.Mapping....

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

更改您的会员签名以使其virtual

public virtual PolicyStatus PolicyStatus

NHibernate希望您实体的所有成员都是virtual以便进行绑定。这是必需的,因为在某些情况下NHibernate会创建代理(以实现延迟加载)。如果未标记为virtual,NHibernate将无法实现。

您可以参考this(或archive)文章:

  

该问题的快速答案是:因为我们需要成员是虚拟的才能进行惰性加载魔术/巫毒。

     

答案越长越有趣。任何实际的ORM都必须具有的重要功能是透明的延迟加载。如果通过ORM检索对象,则不希望该对象自动拉入整个对象图(无论如何不是默认情况下),但也不想通过检查是否已加载某些关联来乱码代码但是,然后在必要时加载它们。这是ORM的责任。理想情况下,如果尚未检索数据,则希望能够访问属性并使ORM​​在首次访问这些属性时加载必要的数据。

     

NHibernate具有此功能,但它不需要您从某种NHibernate基类继承或实现任何接口或类似的东西。那么它是怎样工作的?好吧,只要需要延迟加载,NHibernate就会在运行时使用类的代理。好的,那么代理到底是什么?在这种情况下,NHibernate代理是在为应用程序初始化NHibernate时动态生成的类型(这种情况仅在应用程序启动时发生一次)。将为尚未显式映射的每个实体生成一个代理类型,以避免延迟加载(稍后会详细介绍)。您其中一个实体的代理类型实际上将从您的实体继承,然后拦截您可以对该类型执行的每个可能的调用。