NHibernate:保留一个带有子对象的对象

标签 nhibernate

我正在尝试保留一个带有子对象集合的对象。我不能先坚持 child ,因为有FK关系。我可以先保存父级,然后将子级添加到其中,但这会带来更多工作。基本上,我只是想一步一步保存一个完全填充的对象,而不是将其分成几部分。我的映射有问题吗(抱歉它看起来太丑了)还是我的方法有问题?

父级:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class name="NetworkOrderManagement.Core.Order, NetworkOrderManagement.Core" table="NETORDMGMT.ORDERHEADER" lazy="false" >
    <id name="OrderId" column="ORDERID" type="int">
      <generator class="seqhilo">
        <param name="sequence">ORDERID_SEQ</param>
      </generator>
    </id>
    <property name="TransmissionDate" column="TRANSMISSIONDATE" type="DateTime"/>
    <property name="StoreNumber" column="STORENUMBER" type="Int16"/>
    <property name="Department" column="DEPARTMENT" type="Int16"/>
    <property name="OrderType" column="ORDERTYPE" type="Int16"/>
    <property name="OrderSequence" column="ORDERSEQUENCE" type="Int16"/>
    <property name="ExtractTime" column="EXTRACTTIME" type="DateTime"/>
    <property name="Status" column="STATUS" type="Int16"/>
    <property name="ReceivedTime" column="RECEIVEDTIME" type="DateTime"/>
    <bag name="OrderDetail" table="NETORDMGMT.ORDERDETAIL" 
         lazy="false" cascade="all" inverse="true">
      <key column="ORDERID" on-delete="cascade"/>
      <one-to-many class="NetworkOrderManagement.Core.OrderDetail, NetworkOrderManagement.Core"  />
    </bag>
  </class>
</hibernate-mapping>

child :

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class name="NetworkOrderManagement.Core.OrderDetail, NetworkOrderManagement.Core" table="NETORDMGMT.ORDERDETAIL" lazy="false">
    <id name="OrderDetailId" column="ORDERDETAILID" type="int">
      <generator class="seqhilo">
        <param name="sequence">"ORDERDTLID_SEQ"</param>
      </generator>
    </id>
<many-to-one name="Order" class="NetworkOrderManagement.Core.Order, NetworkOrderManagement.Core"
                 column="OrderId" lazy="false" not-null="true" />
    <property name="ItemNumber" column="ITEMNUMBER" type="Int32"/>
    <property name="OrderQuantity" column="ORDERQUANTITY" type="Int32"/>
    <property name="ErrorCode" column="ERRORCODE" type="Int32"/>
  </class>
</hibernate-mapping>

这是我的异常(exception):

Test method NetworkOrderManagement.Tests.DataAccess.QuickTests.QuickTest threw exception:
Distribution.Exceptions.DataAccessException: NHibernate Exception --->
NHibernate.PropertyValueException: not-null property references a null or transient valueNetworkOrderManagement.Core.OrderDetail.Order.

当我下面的测试尝试在订单仍然处于 transient 时向订单添加订单详细信息时,我得到了这个信息:

    [TestMethod]
    public void QuickTest()
    {
        myOrderRepository = NetworkOrderManagement.Data.RepositoryFactory.Instance.GetOrderRepository();
        myOrderDetailRepository = NetworkOrderManagement.Data.RepositoryFactory.Instance.GetOrderDetailRepository();
        myOrder = new Order { StoreNumber = RandGen.LittleRand(), Department = RandGen.LittleRand(), TransmissionDate = DateTime.MinValue, ExtractTime = DateTime.MinValue, ReceivedTime = DateTime.MinValue };
        myOrder = myOrderRepository.Save(myOrder);

        myOrderDetail1 = new OrderDetail {OrderId = myOrder.OrderId, ItemNumber = RandGen.BigRand(), OrderQuantity = RandGen.LittleRand() };
        myOrderDetail2 = new OrderDetail {OrderId = myOrder.OrderId, ItemNumber = RandGen.BigRand(), OrderQuantity = RandGen.LittleRand() };
        myOrderDetail1 = myOrderDetailRepository.Save(myOrderDetail1);
        myOrderDetail2 = myOrderDetailRepository.Save(myOrderDetail2);
        myOrder.OrderDetail.Add(myOrderDetail1);
        myOrder.OrderDetail.Add(myOrderDetail2);

        myOrderRepository.CommitChanges();

        myOrderDetailRepository.Delete(myOrderDetail2);
        myOrderRepository.CommitChanges();
        myOrderRepository.Delete(myOrder);
        myOrderRepository.CommitChanges();
    }

最佳答案

在集合上指定级联,然后让 NHibernate 为您解决

http://ayende.com/Blog/archive/2006/12/02/NHibernateCascadesTheDifferentBetweenAllAlldeleteorphansAndSaveupdate.aspx

http://www.hibernate.org/hib_docs/nhibernate/1.2/reference/en/html/example-parentchild.html

好的,我已经看到你已经这么做了。 :) 您还没有做的是指定反向引用。 我的意思是:您将一个项目添加到您的集合中,但是这个添加的项目有一个其所有者的属性,您尚未设置该属性:

Order o = new Order();

OrderDetail detail = new OrderDetail ();

detail.Order = o;
o.OrderLines.Add (detail);

更好的(恕我直言)是这个(简化的):

public class Order
{
    private IList<OrderDetail> _details = new List<OrderDetail>();

    public ReadOnlyCollection<OrderDetail> Details
    {
       return new List(_details).AsReadOnly();
    }

    public void AddOrderLine( OrderDetail d )
    {
        d.Order = this;
        _details.Add (d);
    }

    public void RemoveOrderLine( OrderDetail d )
    {
        _details.Remove (d);
    }
}

关于NHibernate:保留一个带有子对象的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/721363/

相关文章:

nhibernate - IStatelessSession 与 ISession 包装器

.net - 休眠多对多删除

nhibernate - fluent nhibernate r1.0 fluent 映射禁用延迟加载

nhibernate - NHibernateUtil.Initialize 做什么?

nhibernate - 持久性无知可以扩展吗?

sql-server - Nhibernate:如何找到SqlDateTime溢出异常的负责字段

NHibernate 在断开连接的情况下

oracle - 如何通过 NHibernate 从 oracle 序列获取 NextVal

c# - Entity Framework - 多项目支持

nhibernate - Hibernate 查询语言中的 IFNULL 等价物?