2009-04-06 5 views
1

Ich versuche, ein Objekt mit einer Sammlung von untergeordneten Objekten zu erhalten. Ich kann die Kinder nicht zuerst bestehen, da es eine FK-Beziehung gibt. Ich könnte zuerst die Eltern speichern und dann die Kinder hinzufügen, aber das würde mehr Arbeit bringen. Im Grunde versuche ich nur, ein vollständig gefülltes Objekt in einem Schritt zu speichern und nicht in Teile zu zerlegen. Ist etwas falsch mit meiner Zuordnung (tut mir leid, es sieht so hässlich) oder ist es meine Methoden?NHibernate: Ein Objekt mit Kindern beibehalten

Parent:

<?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> 

Kind:

<?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> 

Hier ist meine Ausnahme:

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. 

ich das bekommen, wenn mein Test unten versucht, eine Orderdetail der Reihenfolge, während es hinzufügen ist immer noch vorübergehend:

[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(); 
    } 

Antwort

6

Geben Sie auf der Sammlung Kaskadierung und lassen NHibernate es

für Sie herauszufinden

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

Okay, ich habe gesehen, dass Sie das getan haben. :) Was Sie nicht getan haben, ist die Rückreferenz anzugeben. ich meine: Sie einen Artikel zu Ihrer Sammlung hinzufügen, aber das hinzugefügte Element eine Eigenschaft zu seinem Besitzer hat, die Sie nicht festgelegt haben:

Order o = new Order(); 

OrderDetail detail = new OrderDetail(); 

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

Was noch besser (imho) ist dies (vereinfacht) wäre :

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); 
    } 
} 
+0

Arbeitete gut, danke für Ihre Eingabe! –

Verwandte Themen