流利的Nhibernate:意外的行数:0;预期:1

时间:2010-10-28 17:03:08

标签: nhibernate fluent-nhibernate has-many

**截至目前已解决。请参阅编辑2和编辑3 **

我是NHibernate Newbie-一周大了,但我使用它会节省我在新项目上的时间,而不是其他。我一直在试图让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");
    }
}

我正在尝试执行 Has Many 操作。现在我被认为(来自SO和博客中的许多其他帖子)除非我在OrderItems中有一个Orders类引用,否则它是不可能的

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剖析器中看到,如Joseph所说:

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:更新语句的解决方案

在Child Class Map中,将ID行更改为:

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

编辑3:改进插入

基于上面的代码,NH profiler将显示对于每个持久化的对象实例,它将首先生成一个select语句,它将根据该语句确定对象实例是新的还是脏的。为了避免它使用Interceptor作为

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

导航到文章的最底部,您将在其中找到有关如何实现Interceptor的信息。 持久化类将是您需要保存到数据库的实体的基类。拦截器需要在会话中注册

我读过拦截器已被事件取代。无法阅读很多,但拦截器对我来说很有用。

2 个答案:

答案 0 :(得分:2)

你不应该需要这一行

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

我认为这可能会搞砸你。

此外,当您引用订单时,您需要为其指定外键字段的名称,它看起来是您现在没有的。

所以你应该有这个

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

答案 1 :(得分:0)

你的OrderLineMap类不应该有这个:

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

而不是这个:     参考文献(oi =&o; Order,“id”) ?