代码之家  ›  专栏  ›  技术社区  ›  Andy

fluent nhibernate-映射列表会导致nullreferenceexception?

  •  1
  • Andy  · 技术社区  · 14 年前

    我有以下类和流畅的映射:

      public class A {
        public virtual int Id { get; private set; }
        public virtual string MyString { get; set; }
        public virtual IList<B> MyChildren { get; set; }
     }
    
      public class B {
        public virtual int Id { get; private set; }
        public virtual DateTime TheDate { get; set; }
      }
    
      public sealed class AMap : ClassMap<A> {
        public AMap() {
          Id(x => x.Id).GeneratedBy.Native().UnsavedValue(0);
          Map(x => x.MyString);
          HasMany(x => x.MyChildren).AsList(x => x.Column("Ordinal")).KeyColumn("AId").Not.KeyNullable();
        }
      }
    
      public sealed class BMap : ClassMap<B> {
        public BMap() {
          Id(x => x.Id).GeneratedBy.Native().UnsavedValue(0);
          Map(x => x.TheDate);
        }
      }
    

    这将导致以下映射:

      <class xmlns="urn:nhibernate-mapping-2.2" mutable="true" name="A" table="`A`">
        <id name="Id" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" unsaved-value="0">
          <column name="Id" />
          <generator class="native" />
        </id>
        <property name="MyString" type="AnsiString">
          <column name="MyString" length="150" not-null="true" />
        </property>
        <list name="MyChildren" mutable="true">
          <key not-null="true">
            <column name="AId" />
          </key>
          <index>
            <column name="Ordinal" />
          </index>
          <one-to-many class="B" />
        </list>
      </class>
    

    但当我实际尝试保存的实例 NullReferenceException :

    System.NullReferenceException : Object reference not set to an instance of an object.
    at NHibernate.Collection.PersistentList.GetSnapshot(ICollectionPersister persister)
    at NHibernate.Engine.CollectionEntry..ctor(ICollectionPersister persister, IPersistentCollection collection)
    at NHibernate.Engine.StatefulPersistenceContext.AddNewCollection(ICollectionPersister persister, IPersistentCollection collection)
    at NHibernate.Event.Default.WrapVisitor.ProcessArrayOrNewCollection(Object collection, CollectionType collectionType)
    at NHibernate.Event.Default.WrapVisitor.ProcessCollection(Object collection, CollectionType collectionType)
    at NHibernate.Event.Default.AbstractVisitor.ProcessValue(Object value, IType type)
    at NHibernate.Event.Default.WrapVisitor.ProcessValue(Int32 i, Object[] values, IType[] types)
    at NHibernate.Event.Default.AbstractVisitor.ProcessEntityPropertyValues(Object[] values, IType[] types)
    at NHibernate.Event.Default.AbstractSaveEventListener.VisitCollectionsBeforeSave(Object entity, Object id, Object[] values, IType[] types, IEventSource source)
    at NHibernate.Event.Default.AbstractSaveEventListener.PerformSaveOrReplicate(Object entity, EntityKey key, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
    at NHibernate.Event.Default.AbstractSaveEventListener.PerformSave(Object entity, Object id, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
    at NHibernate.Event.Default.AbstractSaveEventListener.SaveWithGeneratedId(Object entity, String entityName, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
    at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event)
    at NHibernate.Event.Default.DefaultSaveEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event)
    at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.EntityIsTransient(SaveOrUpdateEvent event)
    at NHibernate.Event.Default.DefaultSaveEventListener.PerformSaveOrUpdate(SaveOrUpdateEvent event)
    at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate(SaveOrUpdateEvent event)
    at NHibernate.Impl.SessionImpl.FireSave(SaveOrUpdateEvent event)
    at NHibernate.Impl.SessionImpl.Save(Object obj)
    

    我在这里做错什么了?

    澄清:这就是我如何使用这些课程:

    var a = new A { MyChildren = new List<B> { new B { TheDate = DateTime.Now } } };
    a.MyChildren[0].Parent = a;
    
    session.Save(a);
    
    3 回复  |  直到 14 年前
        1
  •  1
  •   DanP    14 年前

    你应该增加 MyChildren = New List<B>(); 为您的构造函数

        2
  •  0
  •   DanP    14 年前

    您的关键字列不应该是“id”(而不是“aid”)吗?我认为这是你问题的根源…

        3
  •  0
  •   Andy    14 年前

    我知道了。上面的示例确实有效,但我试图复制的问题仍然在运行,导致了相同的错误。抱歉…

    问题是我们已经创建了这个ChildList类,并为MyChildren属性返回了该类。它简单地包装了列表(或者nhibernate用于持久列表的具体列表),但是它负责为从集合中添加或删除的任何实例设置Parent属性。

    显然,在保存新实例时,这会导致NHibernate问题。返回正常的具体清单工作。