1

**現在解決済み。編集2および編集3を参照してください**

私はNHibernate初心者です-1週間前ですが、それを使って作業することで、新しいプロジェクトの時間を節約できます。NhibernateにParent-ChildCollectionをSQLサーバーデータベースに保存させようと頭を悩ませてきました。

代替テキスト

私のクラスマップ:

public class OrderMap : ClassMap<Order>
{
    public OrderMap()
    {
        Table("orders");
        Not.LazyLoad();
        Id(x => x.Id,"id");
        Map(x => x.Status, "status").CustomType(typeof(OrderStatus)).Not.Nullable();
        Map(x => x.PurchaseOrder, "purchaseorder").Not.Nullable();
        Map(x => x.SalesOrder, "salesorder").Not.Nullable();
        Map(x => x.SupplierLocationId, "shipfrom").Not.Nullable();
        Map(x => x.CustomerLocationId, "shipto").Not.Nullable();
        Map(x => x.TypeOfShipment, "shipmenttype").CustomType(typeof (ShipmentType)).Not.Nullable();
        HasMany(x => x.OrderLineItems).Table("orderitems").KeyColumns.Add("orderid").Cascade.All();        
    }
}

public class OrderLineMap : ClassMap<OrderLine>
{
    public OrderLineMap()
    {
        Table("orderitems");

        Not.LazyLoad();
        Id(x => x.Id,"id");
        Map(x => x.Order.Id, "orderid").Not.Insert().Not.Update();
        Map(x => x.PartNumber, "partnumber");
        Map(x => x.LineNumber, "linenumber");
        Map(x => x.ReleaseNumber, "releasenumber");
        Map(x => x.Quantity, "quantity");
        Map(x => x.AttachedQuantity, "attached");
        Map(x => x.ActivatedQuantity, "activated");
        Map(x => x.ReshippedQuantity, "reshipped");
        Map(x => x.ReturnRequestQuantity, "requestreturn");
        Map(x => x.ReturnedToSupplierQuantity, "returnedtosupplier");
        Map(x => x.ReturnedFromResellerQuantity, "returnedfromreseller");
        Map(x => x.SplitQuantity, "split");
        Map(x => x.CombineQuantity, "combine");
        Map(x => x.Status, "status").CustomType(typeof(OrderLineStatus));
        Map(x => x.ReferenceOrderId, "reforderid");
        Map(x => x.ReferenceOrderLineId, "reforderlineid");         
        References(oi => oi.Order, "id");
    }
}

HasMany操作を実行しようとしています。今、私は(SOやブログの他の多くの投稿から)OrderItemsにOrdersクラスの参照がないと不可能であると信じさせられました

代替テキスト

NunitとNHProfilerを介してテストを行っており、注文の挿入ステートメントがプロファイリングされています...

OrderTesting.CreateNewOrder : FailedNHibernate.StaleStateException : Unexpected row count: 0; expected: 1
at NHibernate.AdoNet.Expectations.BasicExpectation.VerifyOutcomeNonBatched(Int32 rowCount, IDbCommand statement)
at NHibernate.AdoNet.NonBatchingBatcher.AddToBatch(IExpectation expectation)
at NHibernate.Persister.Collection.AbstractCollectionPersister.PerformInsert(Object ownerId, IPersistentCollection collection, IExpectation expectation, Object entry, Int32 index, Boolean useBatch, Boolean callable, ISessionImplementor session)
at NHibernate.Persister.Collection.AbstractCollectionPersister.Recreate(IPersistentCollection collection, Object id, ISessionImplementor session)
at NHibernate.Action.CollectionRecreateAction.Execute()
at NHibernate.Engine.ActionQueue.Execute(IExecutable executable)
at NHibernate.Engine.ActionQueue.ExecuteActions(IList list)
at NHibernate.Engine.ActionQueue.ExecuteActions()
at NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session)
at NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event)
at NHibernate.Impl.SessionImpl.Flush()
at NHibernate.Transaction.AdoTransaction.Commit()
at Repository.OrderRepository.Save(Order entity) in OrderRepository.cs: line 30

それを解決する方法についての助けはありがたいです。

ありがとうございました、

3月

編集:ジョセフが尋ねたように変更を加えた後、NHプロファイラーに表示される更新ステートメント:

UPDATE orderitems
SET    partnumber = 670712 /* @p0 */,
       linenumber = 1 /* @p1 */,
       releasenumber = 1 /* @p2 */,
       quantity = 2 /* @p3 */,
       attached = 0 /* @p4 */,
       activated = 0 /* @p5 */,
       reshipped = 0 /* @p6 */,
       requestreturn = 0 /* @p7 */,
       returnedtosupplier = 0 /* @p8 */,
       returnedfromreseller = 0 /* @p9 */,
       split = 0 /* @p10 */,
       combine = 0 /* @p11 */,
       status = 0 /* @p12 */,
       reforderid = '00000000-0000-0000-0000-000000000000' /* @p13 */,
       reforderlineid = '00000000-0000-0000-0000-000000000000' /* @p14 */,
       orderid = NULL /* @p15 */
WHERE  id = '66f8c7c6-ece6-47c6-93f0-b8e1975a96dc' /* @p16 */

編集2:更新ステートメントの解決

子クラスマップで、ID行を次のように変更します。

Id(x => x.Id, "id").GeneratedBy.Assigned().UnsavedValue(null);

編集3:インサートを改善する

上記のコードに基づいて、NHプロファイラーは、永続化されているオブジェクトインスタンスごとに、最初にselectステートメントを生成し、それに基づいてオブジェクトインスタンスが新しいかダーティかを判断することを示します。それを回避するには、Interceptorを次のように使用します

http://www.kkaok.pe.kr/doc/hibernate/reference/html/example-parentchild.html

Interceptorの実装方法については、記事の一番下に移動してください。永続クラスは、データベースに保存する必要があるエンティティの基本クラスになります。インターセプターは、セッションを起動するために登録する必要があります

インターセプターがイベントに置き換えられたことを読みました。それについて多くを読むことができませんでしたが、Interceptorは私にとって素晴らしい働きをします。

4

2 に答える 2

2

この行は必要ないはずです

Map(x => x.Order.Id, "orderid").Not.Insert().Not.Update();

それはあなたを台無しにしているかもしれないと思います。

また、 Order を参照するときは、外部キー フィールドの名前を指定する必要があります。これは、現在はないようです。

だからあなたはこれを持っているべきです

References(oi => oi.Order, "orderid");
于 2010-10-28T17:06:04.327 に答える
0

あなたの OrderLineMap クラスにこれがあるべきではありません:

References(oi => oi.Order, "orderid")

これの代わりに: References(oi => oi.Order, "id") ?

于 2010-10-28T17:08:41.180 に答える