Свободный Nhibernate: Неожиданный счетчик строк: 0;ожидается: 1 - PullRequest
1 голос
/ 28 октября 2010

** Решено на данный момент.Пожалуйста, см. Редактировать 2 и Редактировать 3 **

Я новичок NHibernate - неделя, но я, хотя и работаю с ним, сэкономлю мне время на новом проекте, а не иначе.Я бился головой, пытаясь заставить Nhibernate сохранить коллекцию Parent - Child Collection в базу данных сервера SQL.

alt text

Карта моего класса:

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");
    }
}

IЯ пытаюсь выполнить операцию Имеет много .Теперь меня заставили поверить (из множества других постов в SO и Blogs), что это невозможно, если у меня нет ссылки на класс Orders в OrderItems

alt text

Я занимаюсь тестированиемчерез Nunit и NH Profiler и вставка выписки для заказов становится профилированной ...

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

Любая помощь будет благодарна за то, как ее решить.

Спасибо,

Мар

Редактировать: оператор обновления теперь виден в профилировщике 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(x => x.Id, "id").GeneratedBy.Assigned().UnsavedValue(null);

Редактировать 3: Улучшить вставки

На основе приведенного выше кода, NH Profiler покажет, что для каждого сохраняемого экземпляра объекта он сначала генерируетоператор выбора, на основе которого он будет определять, является ли экземпляр объекта новым или грязным.Чтобы избежать этого, используйте Interceptor как

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

Перейдите в самый конец статьи, где вы найдете информацию о том, как реализовать Interceptor.Постоянный класс будет вашим базовым классом для ваших сущностей, которые необходимо сохранить в базе данных.Перехватчик должен быть зарегистрирован во время сеанса

Я прочитал, что перехватчики были заменены событиями.Не могу много читать, но Interceptor отлично работает для меня.

Ответы [ 2 ]

2 голосов
/ 28 октября 2010

Вам не нужна эта строка

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

Я думаю, это может вас испортить.

Кроме того, когда вы ссылаетесь на свой ордер, вам нужно дать ему имя поля внешнего ключа, которое, похоже, у вас сейчас нет.

так что вы должны иметь это

References(oi => oi.Order, "orderid");
0 голосов
/ 28 октября 2010

Разве ваш класс OrderLineMap не должен иметь это:

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

вместо этого: Ссылки (oi => oi.Order, "id")

...