Fluent NHibernate - 用新的 List<object> 子对象保存新的父对象

Posted

技术标签:

【中文标题】Fluent NHibernate - 用新的 List<object> 子对象保存新的父对象【英文标题】:Fluent NHibernate - Save NEW parent object with NEW List<object> children 【发布时间】:2019-11-23 18:53:25 【问题描述】:

我创建了“父”对象。父对象包含一个“子”对象列表。

当我保存父对象时,我希望子对象也被保存,但只有父对象被保存到数据库中。

FluentNHibernate 版本是 1.2.0.712

NHibernate 版本是 3.1.0.4000

我的映射和模型如下。

父模型

namespace Models 
  
    public class OpenSale 
    
        public OpenSale() 
        
            OpenSaleItems = new List<OpenSaleItem>();
        

    public virtual int ID  get; set; 

    public virtual int StaffID  get; set; 
    public virtual int TillID  get; set; 
    public virtual int? FloorTableID  get; set; 
    public virtual int LocationID  get; set; 
    public virtual System.DateTime TimeStarted  get; set; 
    public virtual System.Nullable<System.DateTime> TimeCompleted  get; set; 
    public virtual int? TenderTypeID  get; set; 
    public virtual decimal Amount  get; set; 
    public virtual decimal AmountPaid  get; set; 
    public virtual char SaleCompleted  get; set; 
    public virtual char CompletedOffline  get; set; 
    public virtual string Surname  get; set; 
    public virtual decimal TotalVAT  get; set; 

    public virtual IList<OpenSaleItem> OpenSaleItems  get; set; 

父地图

    using FluentNHibernate.Mapping;
    using Models;

    namespace Maps
    
      public class OpenSaleMap : ClassMap<OpenSale>
      
        public OpenSaleMap()
        
        Table("OpenSale");

        Id(x => x.ID).GeneratedBy.Identity().Column("ID");

        Map(x => x.TimeStarted).Column("TimeStarted").Not.Nullable();
        Map(x => x.TimeCompleted).Column("TimeCompleted");
        Map(x => x.TenderTypeID).Column("TenderTypeID").Nullable();
        Map(x => x.Surname).Column("Surname").Length(30);
        Map(x => x.Amount).Column("Amount").Not.Nullable();
        Map(x => x.AmountPaid).Column("AmountPaid").Not.Nullable();
        Map(x => x.SaleCompleted).Column("SaleCompleted").Not.Nullable().Length(1);
        Map(x => x.CompletedOffline).Column("CompletedOffline").Not.Nullable().Length(1);
        Map(x => x.TotalVAT).Column("TotalVAT").Not.Nullable();
        Map(x => x.StaffID).Column("StaffID");
        Map(x => x.TillID).Column("TillID");
        Map(x => x.FloorTableID).Column("FloorTableID");
        Map(x => x.LocationID).Column("LocationID");

        // WORKS BUT SAVES OPENSALE ONLY
        // HasMany(x => x.OpenSaleItems).KeyColumn("OpenSaleID").Inverse();
        // HasMany(x => x.OpenSaleItems).Cascade.All().KeyColumn("OpenSaleID").Inverse();
        // HasMany(x => x.OpenSaleItems).KeyColumn("OpenSaleID").Inverse();
        // HasMany(x => x.OpenSaleItems).KeyColumn("OpenSaleID");
        // HasMany(x => x.OpenSaleItems).Cascade.AllDeleteOrphan().Table("OpenSaleItem").LazyLoad().KeyColumn("OpenSaleID");


        //HasMany(x => x.OpenSaleItems).Cascade.All().KeyColumn("OpenSaleID");
        // HasMany(x => x.OpenSaleItems).Cascade.SaveUpdate().KeyColumn("OpenSaleID");
        //HasMany(x => x.OpenSaleItems).Inverse().KeyColumn("OpenSaleID");
        // HasMany(x => x.OpenSaleItems).Cascade.All().Table("OpenSaleItem").LazyLoad();
        // HasMany(x => x.OpenSaleItems).Cascade.SaveUpdate().Table("OpenSaleItem");

        //HasMany(x => x.OpenSaleItems).Cascade.All().Table("OpenSaleItem");
        //HasMany(x => x.OpenSaleItems).Table("OpenSaleItem");

        HasMany(x => x.OpenSaleItems)
   .Cascade.All()
   .KeyColumn("OpenSaleID")
   .Inverse() // this is the way how to manage insertions
   .Not
   .LazyLoad();

    

儿童模型

using System.Collections.Generic; 
using System.Text; 
using System; 

namespace Models 
 
  public class OpenSaleItem 
  
    public OpenSaleItem() 
    
    

    public virtual int ID  get; set; 
    public virtual int OpenSaleID  get; set; 
    public virtual int? StockPLU  get; set; 
    public virtual int? RecipeProductID  get; set; 
    public virtual int? SalesUnitID  get; set; 
    public virtual int PriceLevelID  get; set; 
    public virtual int QtyToBePaid  get; set; 
    public virtual int Quantity  get; set; 
    public virtual decimal SalesUnitCostPrice  get; set; 
    public virtual decimal TotalAmount  get; set; 
    public virtual decimal TotalVAT  get; set; 
    public virtual decimal TotalVolume  get; set; 
    public virtual char IsSubSalesUnit  get; set; 

    public virtual OpenSale OpenSale  get; set; 
  

子地图

using FluentNHibernate.Mapping;
using Models;

namespace Maps 
       
  public class OpenSaleItemMap : ClassMap<OpenSaleItem> 
      
    public OpenSaleItemMap() 
    
        Table("OpenSaleItem");

        Id(x => x.ID).GeneratedBy.Identity().Column("ID");

        Map(x => x.Quantity).Column("Quantity").Not.Nullable();
        Map(x => x.SalesUnitCostPrice).Column("SalesUnitCostPrice").Not.Nullable();
        Map(x => x.OpenSaleID).Column("OpenSaleID").Generated.Insert();
        Map(x => x.StockPLU).Column("StockPLU").Nullable();
        Map(x => x.RecipeProductID).Column("RecipeProductID").Nullable();
        Map(x => x.PriceLevelID).Column("PriceLevelID").Not.Nullable();
        Map(x => x.QtyToBePaid).Column("QtyToBePaid").Not.Nullable();
        Map(x => x.SalesUnitID).Column("SalesUnitID").Nullable();
        Map(x => x.TotalAmount).Column("TotalAmount");
        Map(x => x.TotalVAT).Column("TotalVAT");
        Map(x => x.TotalVolume).Column("TotalVolume");
        Map(x => x.IsSubSalesUnit).Column("IsSubSalesUnit");

        References(x => x.OpenSale).Column("OpenSaleID");
    
  

您会注意到在父映射中有很多注释掉的代码行,它们是我尝试过的映射,但只有父记录被保存。

我的目标是使用多个子对象创建父对象并在一个操作中保存。

有一些解决方法 - 但会涉及多次数据库访问或创建存储过程并将子项列表作为数据表传递,但我更愿意坚持一个框架并使用流利的 NH。

任何帮助表示赞赏!谢谢

【问题讨论】:

请不要偷懒 - 使用适当的缩进格式化代码,以便可能尝试回答它的人更容易阅读。 【参考方案1】:

由于您使用的是 Inverse(),因此在客户端也设置关系非常重要。您是否分配了 OpenSaleItem.OpenSale?

如果这不能解决问题,请更新以显示尝试执行创建的实际代码,包括会话和事务管理。

【讨论】:

以上是关于Fluent NHibernate - 用新的 List<object> 子对象保存新的父对象的主要内容,如果未能解决你的问题,请参考以下文章

NHibernate 2 + Fluent Nhibernate 中等信任

NHibernate + Fluent NHibernate 异常

用 Fluent Nhibernate 定义 NHibernate 过滤器的语法?

Fluent NHibernate and Mysql,SQLite

Fluent NHibernate - NHibernate.QueryException:无法解析属性

Fluent Nhibernate and Stored Procedures