1

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

我是 NHibernate 新手 - 一周大,但我虽然使用它可以节省我在新项目上的时间,而不是其他方式。我一直在努力让 Nhibernate 将父子集合保存到 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");
    }
}

我正在尝试进行Has Many操作。现在我(来自 SO 和博客中的许多其他帖子)相信这是不可能的,除非我在 OrderItems 中有一个 Orders 类引用

替代文字

我正在通过 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:更新语句的解决方案

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

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

编辑 3:改进插入

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

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

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

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

4

2 回答 2

2

你不应该需要这条线

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

我想这可能会搞砸你。

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

所以你应该有这个

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 回答